summaryrefslogtreecommitdiff
path: root/addons/survey/views
diff options
context:
space:
mode:
authorstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
committerstephanchrst <stephanchrst@gmail.com>2022-05-10 21:51:50 +0700
commit3751379f1e9a4c215fb6eb898b4ccc67659b9ace (patch)
treea44932296ef4a9b71d5f010906253d8c53727726 /addons/survey/views
parent0a15094050bfde69a06d6eff798e9a8ddf2b8c21 (diff)
initial commit 2
Diffstat (limited to 'addons/survey/views')
-rw-r--r--addons/survey/views/assets.xml69
-rw-r--r--addons/survey/views/gamification_badge_views.xml28
-rw-r--r--addons/survey/views/res_partner_views.xml40
-rw-r--r--addons/survey/views/survey_menus.xml22
-rw-r--r--addons/survey/views/survey_question_views.xml307
-rw-r--r--addons/survey/views/survey_report_templates.xml89
-rw-r--r--addons/survey/views/survey_reports.xml17
-rw-r--r--addons/survey/views/survey_survey_views.xml300
-rw-r--r--addons/survey/views/survey_templates.xml591
-rw-r--r--addons/survey/views/survey_templates_management.xml149
-rw-r--r--addons/survey/views/survey_templates_print.xml56
-rw-r--r--addons/survey/views/survey_templates_statistics.xml422
-rw-r--r--addons/survey/views/survey_templates_user_input_session.xml196
-rw-r--r--addons/survey/views/survey_user_views.xml232
14 files changed, 2518 insertions, 0 deletions
diff --git a/addons/survey/views/assets.xml b/addons/survey/views/assets.xml
new file mode 100644
index 00000000..a05c8f93
--- /dev/null
+++ b/addons/survey/views/assets.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+ <!-- survey assets -->
+ <template id="survey_assets" name="Survey Results assets">
+ <script src="/web/static/lib/Chart/Chart.js"></script>
+
+ <script type="text/javascript" src="/web/static/src/js/fields/field_utils.js"></script>
+
+ <script type="text/javascript" src="/survey/static/src/js/survey_quick_access.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_timer.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_breadcrumb.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_form.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_print.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_result.js" />
+
+ <t t-call="web._assets_helpers">
+ <t t-call="web._assets_frontend_helpers"/>
+ </t>
+ <link href="/survey/static/src/css/survey_print.css" rel="stylesheet" type="text/css"/>
+ <link href="/survey/static/src/css/survey_result.css" rel="stylesheet" type="text/css"></link>
+ <link rel="stylesheet" type="text/scss" href="/survey/static/src/scss/survey_form.scss"/>
+ </template>
+
+ <!-- survey user input session assets -->
+ <template id="survey_user_input_session_assets" name="Survey User Input Session Assets">
+ <script type="text/javascript" src="/survey/static/src/js/libs/chartjs-plugin-datalabels.min.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_session_colors.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_session_chart.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_session_text_answers.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_session_leaderboard.js" />
+ <script type="text/javascript" src="/survey/static/src/js/survey_session_manage.js" />
+ </template>
+
+ <template id="survey_report_assets_pdf" inherit_id="web.report_assets_pdf">
+ <xpath expr="link[last()]" position="after">
+ <link rel="stylesheet" type="text/scss" href="/survey/static/src/scss/survey_reports.scss"/>
+ </xpath>
+ </template>
+
+ <template id="assets_backend" name="survey assets" inherit_id="web.assets_backend">
+ <xpath expr="." position="inside">
+ <link rel="stylesheet" href="/survey/static/src/css/survey_result.css"/>
+ <script type="text/javascript" src="/survey/static/src/js/fields_section_one2many.js"/>
+ <script type="text/javascript" src="/survey/static/src/js/fields_form_page_description.js"/>
+ </xpath>
+ </template>
+
+ <template id="assets_backend_inherit_survey" inherit_id="web.assets_backend" name="Survey backend assets">
+ <xpath expr="link[last()]" position="after">
+ <link rel="stylesheet" type="text/scss" href="/survey/static/src/scss/survey_views.scss"/>
+ </xpath>
+ </template>
+
+ <template id="assets_tests" name="Survey Assets Tests" inherit_id="web.assets_tests">
+ <xpath expr="." position="inside">
+ <script type="text/javascript" src="/survey/static/tests/tours/certification_failure.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/certification_success.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_prefill.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_tour_session_tools.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_tour_session_create.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_tour_session_start.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_tour_session_manage.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_session_manage_test.js"></script>
+ </xpath>
+ </template>
+</data>
+</odoo>
diff --git a/addons/survey/views/gamification_badge_views.xml b/addons/survey/views/gamification_badge_views.xml
new file mode 100644
index 00000000..fa404edf
--- /dev/null
+++ b/addons/survey/views/gamification_badge_views.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo><data>
+ <record id="gamification_badge_form_view_simplified" model="ir.ui.view">
+ <field name="name">gamification.badge.form.view.simplified</field>
+ <field name="model">gamification.badge</field>
+ <field name="priority">100</field>
+ <field name="arch" type="xml">
+ <form string="Badge">
+ <sheet>
+ <div class="oe_button_box" name="button_box"/>
+ <field name="image_1920" widget="image" class="oe_avatar" options="{'preview_image': 'image_128'}"/>
+ <div class="oe_title">
+ <label for="name" class="oe_edit_only"/>
+ <h1>
+ <field name="name" placeholder="Badge Name"/>
+ </h1>
+ </div>
+ <group>
+ <field name="description" nolabel="1" placeholder="Badge Description"/>
+ </group>
+ <group string="Rewards for challenges">
+ <field name="level"/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+</data></odoo>
diff --git a/addons/survey/views/res_partner_views.xml b/addons/survey/views/res_partner_views.xml
new file mode 100644
index 00000000..604e5853
--- /dev/null
+++ b/addons/survey/views/res_partner_views.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo><data>
+
+ <record id="res_partner_action_certifications" model="ir.actions.act_window">
+ <field name="name">Certifications Succeeded</field>
+ <field name="res_model">survey.user_input</field>
+ <field name="view_mode">tree</field>
+ <field name="context">{'search_default_scoring_success': 1}</field>
+ </record>
+
+ <record id="res_partner_view_form" model="ir.ui.view">
+ <field name="name">res.partner.view.form.inherit.survey</field>
+ <field name="model">res.partner</field>
+ <field name="inherit_id" ref="base.view_partner_form"/>
+ <field name="groups_id" eval="[(4, ref('survey.group_survey_user'))]"/>
+ <field name="arch" type="xml">
+ <xpath expr="//div[@name='button_box']" position="inside">
+ <button class="oe_stat_button" type="object"
+ icon="fa-trophy" name="action_view_certifications"
+ attrs="{'invisible': ['|', ('certifications_count', '=', 0), ('is_company', '=', True)]}">
+ <div class="o_field_widget o_stat_info">
+ <span class="o_stat_value"><field name="certifications_count" /></span>
+ <span class="o_stat_text" attrs="{'invisible': [('certifications_count', '&lt;', 2)]}">Certifications</span>
+ <span class="o_stat_text" attrs="{'invisible': [('certifications_count', '&gt;', 1)]}">Certification</span>
+ </div>
+ </button>
+ <button class="oe_stat_button" type="object"
+ icon="fa-trophy" name="action_view_certifications"
+ attrs="{'invisible': ['|', ('certifications_company_count', '=', 0), ('is_company', '=', False)]}">
+ <div class="o_field_widget o_stat_info">
+ <span class="o_stat_value"><field name="certifications_company_count" /></span>
+ <span class="o_stat_text" attrs="{'invisible': [('certifications_company_count', '&lt;', 2)]}">Certifications</span>
+ <span class="o_stat_text" attrs="{'invisible': [('certifications_company_count', '&gt;', 1)]}">Certification</span>
+ </div>
+ </button>
+ </xpath>
+ </field>
+ </record>
+
+</data></odoo>
diff --git a/addons/survey/views/survey_menus.xml b/addons/survey/views/survey_menus.xml
new file mode 100644
index 00000000..2f87d818
--- /dev/null
+++ b/addons/survey/views/survey_menus.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <!-- Main menu -->
+ <menuitem name="Surveys"
+ id="menu_surveys"
+ sequence="70"
+ groups="group_survey_user"
+ web_icon="survey,static/description/icon.png"/>
+
+ <!-- Parent menus -->
+ <menuitem name="Questions"
+ id="survey_menu_questions"
+ parent="menu_surveys"
+ groups="base.group_no_one"
+ sequence="80"/>
+ <menuitem name="Participations"
+ id="survey_menu_user_inputs"
+ parent="menu_surveys"
+ sequence="90"/>
+ </data>
+</odoo>
diff --git a/addons/survey/views/survey_question_views.xml b/addons/survey/views/survey_question_views.xml
new file mode 100644
index 00000000..d9e7bedc
--- /dev/null
+++ b/addons/survey/views/survey_question_views.xml
@@ -0,0 +1,307 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+ <!-- QUESTIONS -->
+ <record model="ir.ui.view" id="survey_question_form">
+ <field name="name">Form view for survey question</field>
+ <field name="model">survey.question</field>
+ <field name="arch" type="xml">
+ <form string="Survey Question" create="false">
+ <field name="is_page" invisible="1"/>
+ <field name="page_id" invisible="1" required="False"/>
+ <field name="survey_id" invisible="1"/>
+ <field name="sequence" invisible="1"/>
+ <field name="scoring_type" invisible="1"/>
+ <sheet>
+ <div class="oe_title" style="width: 100%;">
+ <label for="title" string="Section" attrs="{'invisible': [('is_page', '=', False)]}"/>
+ <label for="title" string="Question" attrs="{'invisible': [('is_page', '=', True)]}"/>
+ <separator />
+ <field name="title" colspan="4"/>
+ <separator />
+ <field name="questions_selection" invisible="1"/>
+ </div>
+ <group class="o_label_nowrap" attrs="{'invisible': ['|', ('is_page', '=', False), ('questions_selection', '=', 'all')]}">
+ <field name="random_questions_count"/>
+ </group>
+ <group attrs="{'invisible': [('is_page', '=', True)]}">
+ <group>
+ <field name="question_type" widget="radio" attrs="{'required': [('is_page', '=', False)]}" />
+ </group>
+ <group>
+ <div class="col-lg-6 offset-lg-3 o_preview_questions">
+ <!-- Multiple Lines Text Zone -->
+ <div attrs="{'invisible': [('question_type', '!=', 'text_box')]}">
+ <i class="fa fa-align-justify fa-4x" role="img" aria-label="Multiple lines" title="Multiple Lines"/>
+ </div>
+ <!-- Single Line Text Zone -->
+ <div attrs="{'invisible': [('question_type', '!=', 'char_box')]}">
+ <i class="fa fa-minus fa-4x" role="img" aria-label="Single Line" title="Single Line"/>
+ </div>
+ <!-- Numerical Value -->
+ <div attrs="{'invisible': [('question_type', '!=', 'numerical_box')]}">
+ <i class="fa fa-2x" role="img" aria-label="Numeric" title="Numeric">123..</i>
+ </div>
+ <!-- Date -->
+ <div attrs="{'invisible': [('question_type', '!=', 'date')]}">
+ <p class="o_datetime">YYYY-MM-DD
+ <i class="fa fa-calendar fa-2x" role="img" aria-label="Calendar" title="Calendar"/>
+ </p>
+ </div>
+ <!-- Date and Time -->
+ <div attrs="{'invisible': [('question_type', '!=', 'datetime')]}">
+ <p class="o_datetime">YYYY-MM-DD hh:mm:ss
+ <i class="fa fa-calendar fa-2x" role="img" aria-label="Calendar" title="Calendar"/>
+ </p>
+ </div>
+ <!-- Multiple choice: only one answer -->
+ <div attrs="{'invisible': [('question_type', '!=', 'simple_choice')]}" role="img" aria-label="Multiple choice with one answer" title="Multiple choice with one answer">
+ <div class="row"><i class="fa fa-circle-o fa-lg"/> answer</div>
+ <div class="row"><i class="fa fa-dot-circle-o fa-lg"/> answer</div>
+ <div class="row"><i class="fa fa-circle-o fa-lg"/> answer</div>
+ </div>
+ <!-- Multiple choice: multiple answers allowed -->
+ <div attrs="{'invisible': [('question_type', '!=', 'multiple_choice')]}" role="img" aria-label="Multiple choice with multiple answers" title="Multiple choice with multiple answers">
+ <div class="row"><i class="fa fa-square-o fa-lg"/> answer</div>
+ <div class="row"><i class="fa fa-check-square-o fa-lg"/> answer</div>
+ <div class="row"><i class="fa fa-square-o fa-lg"/> answer</div>
+ </div>
+ <!-- Matrix -->
+ <div attrs="{'invisible': [('question_type', '!=', 'matrix')]}">
+ <div class="row o_matrix_head">
+ <div class="col-lg-3"></div>
+ <div class="col-lg-3">ans</div>
+ <div class="col-lg-3">ans</div>
+ <div class="col-lg-3">ans</div>
+ </div>
+ <div class="row o_matrix_row">
+ <div class="col-lg-3">Row1</div>
+ <div class="col-lg-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
+ <div class="col-lg-3"><i class="fa fa-dot-circle-o fa-lg" role="img" aria-label="Checked" title="Checked"/></div>
+ <div class="col-lg-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
+ </div>
+ <div class="row o_matrix_row">
+ <div class="col-lg-3">Row2</div>
+ <div class="col-lg-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
+ <div class="col-lg-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
+ <div class="col-lg-3"><i class="fa fa-dot-circle-o fa-lg" role="img" aria-label="Checked" title="Checked"/></div>
+ </div>
+ <div class="row o_matrix_row">
+ <div class="col-lg-3">Row3</div>
+ <div class="col-lg-3"><i class="fa fa-dot-circle-o fa-lg" role="img" aria-label="Checked" title="Checked"/></div>
+ <div class="col-lg-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
+ <div class="col-lg-3"><i class="fa fa-circle-o fa-lg" role="img" aria-label="Not checked" title="Not checked"/></div>
+ </div>
+ </div>
+ </div>
+ </group>
+ </group>
+ <notebook>
+ <page string="Answers" name="answers" attrs="{'invisible': [('is_page', '=', True)]}">
+ <div class="row">
+ <div class="col-6"
+ attrs="{'invisible': [('question_type', 'not in', ['char_box', 'numerical_box', 'date', 'datetime'])]}">
+ <div attrs="{'invisible': [('question_type', '!=', 'char_box')]}">
+ <field name="validation_email" nolabel="1"/>
+ <label for="validation_email"/><br />
+
+ <field name="save_as_email" nolabel="1" attrs="{'invisible': [('validation_email', '=', False)]}"/>
+ <label for="save_as_email" attrs="{'invisible': [('validation_email', '=', False)]}"/>
+ <br attrs="{'invisible': [('validation_email', '=', False)]}"/>
+
+ <field name="save_as_nickname" nolabel="1"/>
+ <label for="save_as_nickname"/>
+ </div>
+ <div>
+ <field name="validation_required" nolabel="1"/>
+ <label for="validation_required"/>
+ <group attrs="{'invisible': [('validation_required', '=', False)]}">
+ <field name="validation_length_min" attrs="{'invisible': [('question_type', '!=', 'char_box')]}"/>
+ <field name="validation_length_max" attrs="{'invisible': [('question_type', '!=', 'char_box')]}"/>
+ <field name="validation_min_float_value" attrs="{'invisible': [('question_type', '!=', 'numerical_box')]}"/>
+ <field name="validation_max_float_value" attrs="{'invisible': [('question_type', '!=', 'numerical_box')]}"/>
+ <field name="validation_min_date" attrs="{'invisible': [('question_type', '!=', 'date')]}"/>
+ <field name="validation_max_date" attrs="{'invisible': [('question_type', '!=', 'date')]}"/>
+ <field name="validation_min_datetime" widget="datetime" attrs="{'invisible': [('question_type', '!=', 'datetime')]}"/>
+ <field name="validation_max_datetime" widget="datetime" attrs="{'invisible': [('question_type', '!=', 'datetime')]}"/>
+ <field name="validation_error_msg"/>
+ </group>
+ </div>
+ </div>
+
+ <div class="col-6" attrs="{'invisible': [
+ '|', ('scoring_type', '=', 'no_scoring'),
+ ('question_type', 'not in', ['numerical_box', 'date', 'datetime'])]
+ }">
+ <group>
+ <field name="answer_numerical_box" string="Correct Answer" attrs="{'invisible': [('question_type', '!=', 'numerical_box')]}"/>
+ <field name="answer_date" string="Correct Answer" attrs="{'invisible': [('question_type', '!=', 'date')]}"/>
+ <field name="answer_datetime" string="Correct Answer" attrs="{'invisible': [('question_type', '!=', 'datetime')]}"/>
+ <field name="is_scored_question"/>
+ <field name="answer_score"/>
+ </group>
+ </div>
+ </div>
+ <group attrs="{'invisible': [('question_type', 'not in', ['simple_choice', 'multiple_choice', 'matrix'])]}">
+ <field name="suggested_answer_ids" string="Answers" context="{'default_question_id': active_id}">
+ <tree editable="bottom">
+ <field name="sequence" widget="handle"/>
+ <field name="value" string="Choices"/>
+ <field name="value_image" options="{'accepted_file_extensions': 'image/*'}"
+ attrs="{'column_invisible': ['|', ('parent.allow_value_image', '=', False), ('parent.question_type', '=', 'matrix')]}"/>
+ <field name="is_correct" attrs="{'column_invisible': ['|', ('parent.scoring_type', '=', 'no_scoring'), ('parent.question_type', '=', 'matrix')]}"/>
+ <field name="answer_score" attrs="{'column_invisible': ['|', ('parent.scoring_type', '=', 'no_scoring'), ('parent.question_type', '=', 'matrix')]}"/>
+ </tree>
+ </field>
+ </group>
+ <group attrs="{'invisible': [('question_type', '!=', 'matrix')]}">
+ <field name="matrix_row_ids" context="{'default_matrix_question_id': active_id}" attrs="{'invisible': [('question_type', '!=', 'matrix')]}">
+ <tree editable="bottom">
+ <field name="sequence" widget="handle"/>
+ <field name="value" string="Rows"/>
+ </tree>
+ </field>
+ </group>
+ </page>
+ <page string="Description" name="survey_description">
+ <field name="description" widget="html"/>
+ </page>
+ <page string="Options" name="options" attrs="{'invisible': [('is_page', '=', True)]}">
+ <group string="Constraints">
+ <group>
+ <field name="constr_mandatory" string="Mandatory Answer"/>
+ <field name="constr_error_msg" attrs="{'invisible': [('constr_mandatory', '=', False)]}"/>
+ <field name="matrix_subtype" attrs="{'invisible':[('question_type','not in',['matrix'])],'required':[('question_type','=','matrix')]}"/>
+ </group>
+ </group>
+ <group>
+ <group string="Display" attrs="{'invisible':[('question_type','not in',['simple_choice', 'multiple_choice'])]}">
+ <field name="column_nb" string="Number of columns"/>
+ <field name="allow_value_image"/>
+ </group>
+ <group string="Conditional Display" attrs="{'invisible': [('questions_selection', '=', 'random')]}">
+ <field name="is_conditional"/>
+ <field name="triggering_question_id" options="{'no_open': True, 'no_create': True}"
+ attrs="{'invisible': [('is_conditional','=', False)], 'required': [('is_conditional','=', True)]}"/>
+ <field name="triggering_answer_id" options="{'no_open': True, 'no_create': True}"
+ attrs="{'invisible': ['|', ('is_conditional','=', False), ('triggering_question_id','=', False)],
+ 'required': [('is_conditional','=', True)]}"/>
+ </group>
+ </group>
+ <group string="Allow Comments" attrs="{'invisible':[('question_type','not in',['simple_choice','multiple_choice', 'matrix'])]}">
+ <field name='comments_allowed' />
+ <field name='comments_message' attrs="{'invisible': [('comments_allowed', '=', False)]}"/>
+ <field name='comment_count_as_answer' attrs="{'invisible': ['|', ('comments_allowed', '=', False), ('question_type', 'in', ['matrix'])]}" />
+ </group>
+ <group string="Live Sessions">
+ <label for="is_time_limited" string="Question Time Limit"/>
+ <div>
+ <field name="is_time_limited" nolabel="1"/>
+ <field name="time_limit" nolabel="1" class="oe_inline"
+ attrs="{'invisible': [('is_time_limited', '=', False)]}" />
+ <span attrs="{'invisible': [('is_time_limited', '=', False)]}"> seconds</span>
+ </div>
+ </group>
+ </page>
+ </notebook>
+ </sheet>
+ </form>
+ </field>
+ </record>
+ <record model="ir.ui.view" id="survey_question_tree">
+ <field name="name">Tree view for survey question</field>
+ <field name="model">survey.question</field>
+ <field name="arch" type="xml">
+ <tree string="Survey Question" create="false">
+ <field name="sequence" widget="handle"/>
+ <field name="title"/>
+ <field name="survey_id"/>
+ <field name="question_type"/>
+ <field name="triggering_question_id" invisible="1"/>
+ <button icon="fa-code-fork" attrs="{'invisible': [('triggering_question_id', '=', False)]}"
+ title="This question depends on another question's answer." class="icon_rotates"/>
+ </tree>
+ </field>
+ </record>
+ <record model="ir.ui.view" id="survey_question_search">
+ <field name="name">Search view for survey question</field>
+ <field name="model">survey.question</field>
+ <field name="arch" type="xml">
+ <search string="Search Question">
+ <field name="title"/>
+ <field name="survey_id" string="Survey"/>
+ <field name="question_type" string="Type"/>
+ <group expand="1" string="Group By">
+ <filter name="group_by_type" string="Type" domain="[]" context="{'group_by':'question_type'}"/>
+ <filter name="group_by_survey" string="Survey" domain="[]" context="{'group_by':'survey_id'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_survey_question_form">
+ <field name="name">Questions</field>
+ <field name="res_model">survey.question</field>
+ <field name="view_mode">tree,form</field>
+ <field name="search_view_id" ref="survey_question_search"/>
+ <field name="context">{'search_default_group_by_page': True}</field>
+ <field name="domain">[('is_page', '=', False)]</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ No questions found
+ </p>
+ </field>
+ </record>
+
+ <!-- LABELS -->
+ <record id="survey_question_answer_view_tree" model="ir.ui.view">
+ <field name="name">survey.question.answer.view.tree</field>
+ <field name="model">survey.question.answer</field>
+ <field name="arch" type="xml">
+ <tree string="Survey Label" create="false">
+ <field name="sequence" widget="handle"/>
+ <field name="question_id"/>
+ <field name="matrix_question_id"/>
+ <field name="value"/>
+ <field name="answer_score" groups="base.group_no_one"/>
+ </tree>
+ </field>
+ </record>
+ <record id="survey_question_answer_view_search" model="ir.ui.view">
+ <field name="name">survey.question.answer.view.search</field>
+ <field name="model">survey.question.answer</field>
+ <field name="arch" type="xml">
+ <search string="Search Label">
+ <field name="question_id"/>
+ <group expand="1" string="Group By">
+ <filter name="group_by_question" string="Question" domain="[]" context="{'group_by':'question_id'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record id="survey_question_answer_action" model="ir.actions.act_window">
+ <field name="name">Suggested Values</field>
+ <field name="res_model">survey.question.answer</field>
+ <field name="view_mode">tree,form</field>
+ <field name="search_view_id" ref="survey_question_answer_view_search"/>
+ <field name="context">{'search_default_group_by_question': True}</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ No survey labels found
+ </p>
+ </field>
+ </record>
+
+ <menuitem name="Questions"
+ id="menu_survey_question_form1"
+ action="action_survey_question_form"
+ parent="survey_menu_questions"
+ sequence="2"/>
+ <menuitem name="Suggested Values"
+ id="menu_survey_label_form1"
+ action="survey_question_answer_action"
+ parent="survey_menu_questions"
+ sequence="3"/>
+</data>
+</odoo>
diff --git a/addons/survey/views/survey_report_templates.xml b/addons/survey/views/survey_report_templates.xml
new file mode 100644
index 00000000..3f3d3767
--- /dev/null
+++ b/addons/survey/views/survey_report_templates.xml
@@ -0,0 +1,89 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <template id="certification_report_view_modern">
+ <!-- Style classes to be applyed to '#o_survey_certification': [no class](purple), gold, blue -->
+ <div id="o_survey_certification" t-att-data-oe-model="user_input._name" t-att-data-oe-id="user_input.id" t-att-class="'article certification-wrapper modern %s' % layout_color">
+ <div class="certification">
+ <div t-if="user_input.test_entry" class="test-entry"/>
+ <div class="certification-top">
+ <div class="certification-bg-dark">
+ <div class="certification-company-wrapper" t-field="user_input.survey_id.create_uid.company_id.logo" t-options="{'widget': 'image'}" role="img"/>
+ </div>
+ <div class="certification-name" t-field="user_input.survey_id.display_name"/>
+ </div>
+
+ <div class="certification-bottom">
+ <div t-if="user_input.scoring_success">
+ <h5 class="user-name-label">This Certificate is Presented to</h5>
+ <div class="user-name" t-esc="user_input.partner_id.name or user_input.email"/>
+
+ <div class="certification-description">
+ <span t-field="user_input.survey_id.create_uid.company_id.display_name"/> is proud to award this certificate to
+ <span t-esc="user_input.partner_id.name or user_input.email"/> for graduating <span t-field="user_input.survey_id.display_name"/>.
+ </div>
+ </div>
+ <div t-else="">
+ <h5>Certification Failed</h5>
+ </div>
+
+ <div class="certification-bottom-group">
+ <div class="certification-bg-dark"/>
+ <div class="certification-date">
+ <h5>Date</h5>
+ <h5 t-field="user_input.create_date" t-options='{"widget": "date"}'/>
+ </div>
+ <div class="certification-seal">
+ <img src="/survey/static/src/img/certification_seal.svg" alt="Certification Seal" role="image"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </template>
+
+ <template id="certification_report_view_classic">
+ <!-- Style classes to be applyed to '#o_survey_certification': [no class](purple), gold, blue -->
+ <div id="o_survey_certification" t-att-data-oe-model="user_input._name" t-att-data-oe-id="user_input.id" t-att-class="'article certification-wrapper classic %s' % layout_color">
+ <div class="certification">
+ <div t-if="user_input.test_entry" class="test-entry"/>
+ <h5 class="certification-name-label">CERTIFICATE</h5>
+ <div class="certification-name" t-field="user_input.survey_id.display_name"/>
+ <hr/>
+
+ <div t-if="user_input.scoring_success">
+ <h5>This Certificate is Presented to</h5>
+ <div class="user-name" t-esc="user_input.partner_id.name or user_input.email"/>
+ <hr class="small"/>
+
+ <div class="certification-description">
+ <span t-field="user_input.survey_id.create_uid.company_id.display_name"/> is proud to award this certificate to
+ <span t-esc="user_input.partner_id.name or user_input.email"/> for graduating <span t-field="user_input.survey_id.display_name"/>.
+ </div>
+ </div>
+ <div t-else="">
+ <h5>Certification Failed</h5>
+ </div>
+
+ <div class="certification-date" t-field="user_input.create_date" t-options='{"widget": "date"}'/>
+ <img src="/survey/static/src/img/certification_seal.svg" alt="Certification Seal" role="img"/>
+
+ <div class="certificate-signature">
+ <span t-field="user_input.survey_id.create_uid.company_id.logo" t-options="{'widget': 'image'}" role="img"/>
+ </div>
+ </div>
+ </div>
+ </template>
+
+ <template id="certification_report_view">
+ <t t-call="web.html_container">
+ <t t-foreach="docs" t-as="user_input">
+ <t t-set="layout_values" t-value="user_input.survey_id.certification_report_layout.split('_') if user_input.survey_id.certification_report_layout else ['modern', 'purple']"/>
+ <t t-set="layout_template" t-value="'survey.certification_report_view_%s' % (layout_values[0])"/>
+ <t t-set="layout_color" t-value="layout_values[1]"/>
+ <t t-call="{{layout_template}}"/>
+ </t>
+ </t>
+ </template>
+ </data>
+</odoo>
diff --git a/addons/survey/views/survey_reports.xml b/addons/survey/views/survey_reports.xml
new file mode 100644
index 00000000..7293b0b1
--- /dev/null
+++ b/addons/survey/views/survey_reports.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+ <data>
+ <!-- QWeb Reports -->
+ <record id="certification_report" model="ir.actions.report">
+ <field name="name">Certifications</field>
+ <field name="model">survey.user_input</field>
+ <field name="report_type">qweb-pdf</field>
+ <field name="report_name">survey.certification_report_view</field>
+ <field name="report_file">survey.certification_report_view</field>
+ <field name="print_report_name">'Certification - %s' % (object.survey_id.display_name)</field>
+ <field name="attachment">'certification.pdf'</field>
+ <field name="binding_model_id" ref="model_survey_user_input"/>
+ <field name="binding_type">report</field>
+ </record>
+ </data>
+</odoo>
diff --git a/addons/survey/views/survey_survey_views.xml b/addons/survey/views/survey_survey_views.xml
new file mode 100644
index 00000000..0d206322
--- /dev/null
+++ b/addons/survey/views/survey_survey_views.xml
@@ -0,0 +1,300 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+ <record model="ir.ui.view" id="survey_form">
+ <field name="name">Form view for survey</field>
+ <field name="model">survey.survey</field>
+ <field name="arch" type="xml">
+ <form string="Survey" class="o_survey_form">
+ <field name="id" invisible="1"/>
+ <field name="session_state" invisible="1"/>
+ <header>
+ <button name="action_open" string="Start Survey" type="object" class="oe_highlight" attrs="{'invisible': ['|', ('state', '!=', 'draft'), ('id', '=', False)]}"/>
+ <button name="action_send_survey" string="Share" type="object" class="oe_highlight" states="open"/>
+ <button name="action_result_survey" string="See results" type="object" class="oe_highlight"
+ attrs="{'invisible': ['|', ('state', '=', 'draft'), ('answer_done_count', '&lt;=', 0)]}"/>
+ <button name="action_start_session" string="Create Live Session" type="object"
+ attrs="{'invisible': ['|', ('session_state', '!=', False), '|', ('state', '!=', 'open'), ('certification', '=', True)]}" />
+ <button name="action_open_session_manager" string="Open Session Manager" type="object"
+ attrs="{'invisible': ['|', ('session_state', '=', False), ('state', '=', 'draft')]}" />
+ <button name="action_end_session" string="Close Live Session" type="object"
+ attrs="{'invisible': ['|', ('session_state', 'not in', ['ready', 'in_progress']), ('state', '=', 'draft')]}" />
+ <button name="action_draft" string="Set to draft" type="object" states="closed"/>
+ <button name="action_test_survey" string="Test" type="object" attrs="{'invisible': ['|', ('state', '=', 'closed'), ('id', '=', False)]}"/>
+ <button name="action_print_survey" string="Print" type="object" attrs="{'invisible': [('id', '=', False)]}"/>
+ <button name="action_close" string="Close" type="object" states="open"/>
+ <field name="state" widget="statusbar"/>
+ </header>
+ <sheet>
+ <div class="oe_button_box" name="button_box">
+ <button name="action_survey_user_input"
+ type="object"
+ class="oe_stat_button"
+ attrs="{'invisible': [('access_mode', '=', 'public')]}"
+ icon="fa-envelope-o">
+ <field string="Registered" name="answer_count" widget="statinfo"/>
+ </button>
+ <button name="action_survey_user_input_certified"
+ type="object"
+ class="oe_stat_button"
+ attrs="{'invisible': [('certification', '=', False)]}"
+ icon="fa-trophy">
+ <field string="Certified" name="success_count" widget="statinfo"/>
+ </button>
+ <button name="action_survey_user_input_completed"
+ type="object"
+ class="oe_stat_button"
+ icon="fa-pencil-square-o">
+ <field string="Answers" name="answer_done_count" widget="statinfo"/>
+ </button>
+ </div>
+ <widget name="web_ribbon" title="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
+ <field name="background_image" widget="image" class="oe_avatar"/>
+ <div class="oe_title" style="width: 100%;">
+ <label for="title" class="oe_edit_only"/>
+ <h1><field name="title" placeholder="e.g. Satisfaction Survey"/></h1>
+ </div>
+ <group>
+ <group>
+ <field name="active" invisible="1"/>
+ <field name="has_conditional_questions" invisible="1"/>
+ </group>
+ </group>
+ <notebook>
+ <page string="Questions" name="questions">
+ <field name="question_and_page_ids" nolabel="1" widget="question_page_one2many" mode="tree,kanban" context="{'default_survey_id': active_id, 'default_questions_selection': questions_selection}">
+ <tree decoration-bf="is_page" editable="bottom">
+ <field name="sequence" widget="handle"/>
+ <field name="title" widget="survey_description_page"/>
+ <field name="question_type" />
+ <field name="is_page" invisible="1"/>
+ <field name="questions_selection" invisible="1"/>
+ <field name="survey_id" invisible="1"/>
+ <field name="triggering_question_id" invisible="1"/>
+ <field name="random_questions_count" attrs="{'column_invisible': [('parent.questions_selection', '=', 'all')], 'invisible': [('is_page', '=', False)]}" />
+ <button icon="fa-code-fork" attrs="{'invisible': [('triggering_question_id', '=', False)]}"
+ title="This question depends on another question's answer." class="icon_rotates"/>
+ <control>
+ <create name="add_section_control" string="Add a section" context="{'default_is_page': True, 'default_questions_selection': 'all'}"/>
+ <create name="add_question_control" string="Add a question"/>
+ </control>
+ </tree>
+ </field>
+ </page>
+ <page string="Description" name="description">
+ <field name="description" nolabel="1"></field>
+ </page>
+ <page string="Options" name="options">
+ <group name="options">
+ <group string="Questions" name="questions">
+ <field name="questions_layout" widget="radio"
+ attrs="{'readonly': [('session_state', 'in', ['ready', 'in_progress'])]}"/>
+ <field name="progression_mode" widget="radio" />
+ <label for="is_time_limited" string="Survey Time Limit"/>
+ <div>
+ <field name="is_time_limited" nolabel="1"/>
+ <field name="time_limit" widget="float_time" attrs="{'invisible': [('is_time_limited', '=', False)]}" nolabel="1" class="oe_inline" /> <span attrs="{'invisible': [('is_time_limited', '=', False)]}"> minutes</span>
+ </div>
+ <field name="questions_selection" widget="radio" />
+ <field name="users_can_go_back" string="Back Button" attrs="{'invisible': [('questions_layout', '=', 'one_page')]}"/>
+ </group>
+ <group string="Candidates" name="candidates">
+ <field name="access_mode"/>
+ <field name="users_login_required"/>
+ <label for="is_attempts_limited" string="Attempts Limit"
+ attrs="{'invisible': ['|', ('has_conditional_questions', '=', True), '&amp;', ('access_mode', '=', 'public'), ('users_login_required', '=', False)]}"/>
+ <div attrs="{'invisible': ['|', ('has_conditional_questions', '=', True), '&amp;', ('access_mode', '=', 'public'), ('users_login_required', '=', False)]}">
+ <field name="is_attempts_limited" nolabel="1"/>
+ <field name="attempts_limit" attrs="{'invisible': [('is_attempts_limited', '=', False)]}" nolabel="1" class="oe_inline" /> <span attrs="{'invisible': [('is_attempts_limited', '=', False)]}"> attempts</span>
+ </div>
+ </group>
+ <group string="Scoring" name="scoring">
+ <field name="scoring_type" widget="radio" />
+ <field name="scoring_success_min" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}" />
+ <field name="certification" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}" />
+ <field name="certification_mail_template_id" attrs="{'invisible': [('certification', '=', False)]}" />
+ <label for="certification_report_layout" string="Certification Template" attrs="{'invisible': [('certification', '=', False)]}"/>
+ <div attrs="{'invisible': [('certification', '=', False)]}" class="d-flex">
+ <field name="certification_report_layout" class="oe_inline"/>
+ <button name="action_survey_preview_certification_template"
+ string="Preview" type="object"
+ icon="fa-external-link" target="_blank" class="btn-link pt-0"/>
+ </div>
+ <field name="certification_give_badge" attrs="{'invisible': ['|', ('certification', '=', False), ('users_login_required', '=', False)]}" />
+ <field name="certification_badge_id" attrs="{'invisible': ['|', ('certification_give_badge', '=', False), ('certification_badge_id', '!=', False)]}"
+ domain="[('survey_id', '=', active_id), ('survey_id', '!=', False)]"
+ context="{'default_name': title,
+ 'default_description': 'Congratulations, you have succeeded this certification',
+ 'default_rule_auth': 'nobody',
+ 'default_level': None,
+ 'form_view_ref': 'survey.gamification_badge_form_view_simplified',
+ 'default_website_published': True}"/>
+ <field name="certification_badge_id_dummy" attrs="{'invisible': ['|', ('certification_give_badge', '=', False), ('certification_badge_id', '=', False)]}"
+ options="{'no_create': True}"
+ context="{'form_view_ref': 'survey.gamification_badge_form_view_simplified'}"/>
+ </group>
+ <group string="Live Session">
+ <field name="session_speed_rating" />
+ <div class="o_td_label">
+ <label for="session_code" string="Session Code" class="oe_edit_only o_form_label" />
+ <label for="session_link" string="Session Link" class="oe_read_only o_form_label" />
+ </div>
+ <div class="d-flex">
+ <field name="session_code" nolabel="1" class="mr-2 oe_edit_only" />
+ <field name="session_link" nolabel="1" widget="CopyClipboardChar" class="oe_read_only" />
+ </div>
+ </group>
+ </group>
+ </page>
+ </notebook>
+ </sheet>
+ <div class="oe_chatter">
+ <field name="message_follower_ids"/>
+ <field name="activity_ids"/>
+ <field name="message_ids"/>
+ </div>
+ </form>
+ </field>
+ </record>
+ <record model="ir.ui.view" id= "survey_tree">
+ <field name="name">Tree view for survey</field>
+ <field name="model">survey.survey</field>
+ <field name="arch" type="xml">
+ <tree string="Survey" sample="1">
+ <field name="active" invisible="1"/>
+ <field name="certification" invisible="1"/>
+ <field name="title"/>
+ <field name="state" widget="badge" decoration-info="state == 'draft'" decoration-success="state == 'open'"/>
+ <field name="answer_count"/>
+ <field name="answer_done_count"/>
+ <field name="success_count"/>
+ <field name="success_ratio"/>
+ <field name="answer_score_avg"/>
+ <button name="certification" type="button" disabled="disabled"
+ icon="fa-trophy" title="Certification" aria-label="Certification"
+ attrs="{'invisible': [('certification', '=', False)]}"/>
+ <!-- Tweak as icons aren't directly supported in xml -->
+ </tree>
+ </field>
+ </record>
+ <record model="ir.ui.view" id="survey_kanban">
+ <field name="name">Kanban view for survey</field>
+ <field name="model">survey.survey</field>
+ <field name="arch" type="xml">
+ <kanban sample="1">
+ <field name="state" />
+ <field name="title" />
+ <field name="answer_done_count" />
+ <field name="certification" />
+ <field name="scoring_type" />
+ <field name="color" />
+ <field name="access_mode"/>
+ <field name="activity_ids" />
+ <field name="activity_state" />
+ <field name="success_count"/>
+ <field name="success_ratio"/>
+ <templates>
+ <div t-name="kanban-box"
+ t-attf-class="oe_kanban_color_#{kanban_getcolor(record.color.raw_value)} oe_kanban_card oe_kanban_global_click o_kanban_card_survey
+ #{record.certification.raw_value ? 'o_kanban_card_survey_successed' : ''}">
+ <div class="o_dropdown_kanban dropdown" t-if="widget.editable">
+
+ <a role="button" class="dropdown-toggle o-no-caret btn" data-toggle="dropdown" data-display="static" href="#" aria-label="Dropdown menu" title="Dropdown menu">
+ <span class="fa fa-ellipsis-v"/>
+ </a>
+ <div class="dropdown-menu" role="menu">
+ <a role="menuitem" type="edit" class="dropdown-item">Edit Survey</a>
+ <a t-if="record.state.raw_value != 'closed'" role="menuitem" type="object" class="dropdown-item" name="action_send_survey">Share</a>
+ <a t-if="widget.deletable" role="menuitem" type="delete" class="dropdown-item">Delete</a>
+ <div role="separator" class="dropdown-divider"/>
+ <div role="separator" class="dropdown-item-text">Color</div>
+ <ul class="oe_kanban_colorpicker" data-field="color"/>
+ </div>
+ </div>
+ <div class="o_kanban_record_top">
+ <h4 class="o_kanban_record_title p-0 mb4"><field name="title" /></h4>
+ </div>
+ <div class="row">
+ <div class="col-10 p-0 pb-1">
+ <div class="container o_kanban_card_content" t-if="record.answer_done_count.raw_value != 0 or record.state.raw_value != 'draft'">
+ <div class="row mt-4 ml-5">
+ <div class="col-4 p-0">
+ <a name="action_result_survey" type="object" class="d-flex flex-column align-items-center">
+ <span class="font-weight-bold"><field name="answer_done_count"/></span>
+ <span class="text-muted">Answers</span>
+ </a>
+ </div>
+ <div class="col-4 p-0 border-left" t-if="record.scoring_type.raw_value != 'no_scoring'" >
+ <a name="action_survey_user_input_certified" type="object" class="d-flex flex-column align-items-center">
+ <span class="font-weight-bold"><field name="success_count"/></span>
+ <span class="text-muted" t-if="!record.certification.raw_value">Passed</span>
+ <span class="text-muted" t-else="">Certified</span>
+ </a>
+ </div>
+ <div class="col-4 p-0 border-left" t-if="record.scoring_type.raw_value != 'no_scoring'" >
+ <a name="action_survey_user_input_completed" type="object" class="d-flex flex-column align-items-center">
+ <span class="font-weight-bold"> <t t-esc="Math.round(record.success_ratio.raw_value)"></t> %</span>
+ <span class="text-muted" >Success</span>
+ </a>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="col-2 align-self-end">
+ <div class="o_kanban_record_bottom">
+ <div class="oe_kanban_bottom_left"/>
+ <div class="oe_kanban_bottom_right">
+ <field name="activity_ids" widget="kanban_activity"/>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+ <record id="survey_survey_view_search" model="ir.ui.view">
+ <field name="name">survey.survey.search</field>
+ <field name="model">survey.survey</field>
+ <field name="arch" type="xml">
+ <search string="Survey">
+ <field string="Survey" name="title"/>
+ <filter string="Certification" name="certification" domain="[('certification', '=', True)]"/>
+ <separator/>
+ <filter string="Archived" name="inactive" domain="[('active', '=', False)]"/>
+ <separator/>
+ <filter invisible="1" string="Late Activities" name="activities_overdue"
+ domain="[('my_activity_date_deadline', '&lt;', context_today().strftime('%Y-%m-%d'))]"
+ help="Show all records which has next action date is before today"/>
+ <filter invisible="1" string="Today Activities" name="activities_today"
+ domain="[('my_activity_date_deadline', '=', context_today().strftime('%Y-%m-%d'))]"/>
+ <filter invisible="1" string="Upcoming Activities" name="activities_upcoming_all"
+ domain="[('my_activity_date_deadline', '&gt;', context_today().strftime('%Y-%m-%d'))]"/>
+ <group expand="0" string="Group By">
+ <filter string="State" name="groupby_state" context="{'group_by': 'state'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_survey_form">
+ <field name="name">Surveys</field>
+ <field name="res_model">survey.survey</field>
+ <field name="view_mode">kanban,tree,form,activity</field>
+ <field name="context">{'search_default_groupby_state': 1}</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_smiling_face">
+ Add a new survey
+ </p><p>
+ You can create surveys for different purposes: customer opinion, services feedback, recruitment interviews, employee's periodical evaluations, marketing campaigns, etc.
+ </p><p>
+ Design easily your survey, send invitations and analyze answers.
+ </p>
+ </field>
+ </record>
+
+ <menuitem name="Surveys" id="menu_survey_form" action="action_survey_form" parent="menu_surveys" sequence="1"/>
+
+</data>
+</odoo>
diff --git a/addons/survey/views/survey_templates.xml b/addons/survey/views/survey_templates.xml
new file mode 100644
index 00000000..c1656efa
--- /dev/null
+++ b/addons/survey/views/survey_templates.xml
@@ -0,0 +1,591 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+ <!-- Main survey layout -->
+ <template id="survey.layout" name="Survey Layout" inherit_id="web.frontend_layout" primary="True">
+ <xpath expr="//div[@id='wrapwrap']" position="before">
+ <!--TODO DBE Fix me : If one day, there is a survey_livechat bridge module, put this in that module-->
+ <t t-set="no_livechat" t-value="True"/>
+ </xpath>
+ <xpath expr="//div[@id='wrapwrap']" position="attributes">
+ <attribute name="t-att-style" add="(('height: 100%; overflow: auto; background: url(' + '/survey/get_background_image/%s/%s' % (survey.access_token, answer.access_token) + ') no-repeat fixed center; box-shadow: inset 0 0 0 10000px rgba(255,255,255,.7); background-size: cover;') if survey and survey.background_image and answer else 'height: 100%; overflow: auto;')"/>
+ </xpath>
+ <xpath expr="//head/t[@t-call-assets][last()]" position="after">
+ <t t-call-assets="survey.survey_assets" lazy_load="True"/>
+ </xpath>
+ <xpath expr="//header" position="before">
+ <t t-set="no_header" t-value="True"/>
+ <t t-set="no_footer" t-value="True"/>
+ </xpath>
+ <xpath expr="//header" position="after">
+ <div id="wrap" class="oe_structure oe_empty"/>
+ </xpath>
+ <xpath expr="//footer" position="after">
+ <div class="py-3 m-0 p-0 text-right">
+ <div class="o_survey_progress_wrapper d-inline-block pr-5 text-left">
+ <t t-call="survey.survey_progression"
+ t-if="survey and survey.questions_layout != 'one_page' and answer and answer.state == 'in_progress' and (not question or not question.is_page)">
+ <t t-if="survey.questions_layout == 'page_per_section'">
+ <t t-set="page_ids" t-value="survey.page_ids.ids"/>
+ <t t-set="page_number" t-value="page_ids.index(page.id) + (1 if survey.progression_mode == 'number' else 0)"/>
+ </t>
+ <t t-else="">
+ <t t-set="page_ids" t-value="survey.question_ids.ids"/>
+ <t t-set="page_number" t-value="page_ids.index(question.id)"/>
+ </t>
+ </t>
+ </div>
+ <div class="o_survey_brand_message float-right rounded mr-3 border">
+ <div class="px-2 py-2 d-inline-block" t-call="web.brand_promotion_message">
+ <t t-set="_message"></t>
+ <t t-set="_utm_medium" t-valuef="survey"/>
+ </div>
+ <div class="o_survey_navigation_wrapper d-inline-block" t-call="survey.survey_navigation">
+ </div>
+ </div>
+ </div>
+ </xpath>
+ </template>
+
+ <!-- Main survey template -->
+ <template id="survey_page_fill" name="Survey: main page (take survey)">
+ <t t-call="survey.layout">
+ <t t-if="answer.test_entry" t-call="survey.survey_button_form_view" />
+ <div class="wrap o_survey_wrap d-flex">
+ <div class="container o_survey_form d-flex flex-column mb-5">
+
+ <t t-call="survey.survey_fill_header" />
+ <t t-call="survey.survey_fill_form" />
+ </div>
+ </div>
+ </t>
+ </template>
+
+ <template id="survey_fill_header" name="Survey: main page header">
+ <div class="o_survey_nav pt16 mb-2">
+ <div class="container m-0 p-0">
+ <div class="row">
+ <div class="col-10">
+ <h1 t-if="answer.state == 'new' or survey.questions_layout != 'page_per_question'"
+ t-esc="survey.title" class="o_survey_main_title pt-4"></h1>
+ </div>
+ <div class="o_survey_timer col-2 pt-4">
+ <h1 class="o_survey_timer_container timer text-right">
+ </h1>
+ </div>
+ </div>
+ </div>
+ <div t-att-class="'o_survey_breadcrumb_container mt8' + (' d-none ' if answer.state != 'in_progress' else '')"
+ t-if="not survey.has_conditional_questions and survey.questions_layout == 'page_per_section' and answer.state != 'done'"
+ t-att-data-can-go-back="survey.users_can_go_back"
+ t-att-data-pages="json.dumps(breadcrumb_pages)" />
+ </div>
+ </template>
+
+ <template id="survey_fill_form" name="Survey: main page content">
+ <t t-set="survey_form_readonly" t-value="answer.state == 'done'"/>
+ <form role="form" method="post" t-att-name="survey.id"
+ class="d-flex flex-grow-1 align-items-center"
+ t-att-data-answer-token="answer.access_token"
+ t-att-data-survey-token="survey.access_token"
+ t-att-data-users-can-go-back="survey.users_can_go_back and not answer.is_session_answer"
+ t-att-data-session-in-progress="answer.is_session_answer"
+ t-att-data-is-start-screen="answer.state == 'new'"
+ t-att-data-readonly="survey_form_readonly"
+ t-att-data-has-answered="bool(has_answered)"
+ t-att-data-is-page-description="bool(question and question.is_page and not is_html_empty(question.description))"
+ t-att-data-questions-layout="survey.questions_layout"
+ t-att-data-triggered-questions-by-answer="json.dumps(triggered_questions_by_answer)"
+ t-att-data-selected-answers="json.dumps(selected_answers)">
+ <input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
+ <input type="hidden" name="token" t-att-value="answer.access_token" />
+ <div class="o_survey_error alert alert-danger d-none" role="alert">
+ <p>There was an error during the validation of the survey.</p>
+ </div>
+
+ <div class="o_survey_form_content w-100">
+ <t t-if="answer.state == 'new'" t-call="survey.survey_fill_form_start"/>
+ <t t-elif="answer.state == 'in_progress'" t-call="survey.survey_fill_form_in_progress" />
+ <t t-else="" t-call="survey.survey_fill_form_done"/>
+ </div>
+ </form>
+
+ <!-- Modal used to display error message, i.c.o. ajax error -->
+ <div role="dialog" class="modal fade" id="MasterTabErrorModal" >
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <header class="modal-header">
+ <h4 class="modal-title">A problem has occured</h4>
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close">×</button>
+ </header>
+ <main class="modal-body"><p>To take this survey, please close all other tabs on <strong class="text-danger"></strong>.</p></main>
+ <footer class="modal-footer"><button type="button" class="btn btn-primary" data-dismiss="modal">Continue here</button></footer>
+ </div>
+ </div>
+ </div>
+ </template>
+
+ <template id="survey_fill_form_start" name="Survey: start form content">
+ <div class="wrap o_survey_start">
+ <div class='mb32'>
+ <div t-field='survey.description' class="oe_no_empty pb-5"/>
+ <t t-if="answer.is_session_answer">
+ <div class="font-weight-bold">
+ The session will begin automatically when the host starts.
+ </div>
+ </t>
+ <t t-else="">
+ <div t-if="survey.is_time_limited">
+ <p>
+ <span>Time limit for this survey: </span>
+ <span class="font-weight-bold text-danger" t-field="survey.time_limit" t-options="{'widget': 'duration', 'unit': 'minute'}"></span>
+ </p>
+ </div>
+ <button type="submit" value="start" class="btn btn-primary btn-lg">
+ <t t-if="survey.certification">
+ Start Certification
+ </t>
+ <t t-else="">
+ Start Survey
+ </t>
+ </button>
+ <span class="o_survey_enter font-weight-bold text-muted ml-2">or press Enter</span>
+ </t>
+ </div>
+ </div>
+ </template>
+
+ <template id="survey_fill_form_in_progress" name="Survey: form with questions">
+ <div class="o_survey_form_content_data d-none"
+ t-att-data-question-time-limit-reached="answer.question_time_limit_reached"
+ t-att-data-has-answered="bool(has_answered)"
+ t-att-data-is-page-description="bool(question and question.is_page and not is_html_empty(question.description))"
+ t-att-data-timer="timer_start"
+ t-att-data-time-limit-minutes="time_limit_minutes"/>
+ <t t-if="survey.questions_layout == 'one_page'">
+ <t t-foreach='survey.question_and_page_ids' t-as='question'>
+ <h2 t-if="question.is_page" t-field='question.title' class="o_survey_title pb16" />
+ <div t-if="question.is_page" t-field='question.description'/>
+ <t t-if="not question.is_page and question in answer.predefined_question_ids" t-call="survey.question_container"/>
+ </t>
+
+ <div class="text-center mt16 mb256">
+ <button type="submit" value="finish" class="btn btn-primary">
+ Submit</button><span class="font-weight-bold text-muted ml-2 d-none d-md-inline">or press Enter</span>
+ </div>
+ </t>
+
+ <t t-if="survey.questions_layout == 'page_per_section'">
+ <h2 t-field='page.title' class="o_survey_title pb16" />
+ <div t-field='page.description' class="oe_no_empty"/>
+
+ <input type="hidden" name="page_id" t-att-value="page.id" />
+ <t t-foreach='page.question_ids' t-as='question'>
+ <t t-if="question in answer.predefined_question_ids" t-call="survey.question_container"/>
+ </t>
+
+ <div class="row">
+ <div class="col-12 text-center mt16">
+ <button type="submit" t-att-value="'next' if not survey_last else 'finish'" class="btn btn-primary">
+ <t t-if="not survey_last">Continue</t>
+ <t t-else="">Submit</t>
+ </button><span class="font-weight-bold text-muted ml-2 d-none d-md-inline"> or press Enter</span>
+ </div>
+ </div>
+ </t>
+
+ <!-- If we have a choice question and less than 6 options, we want minimized display.
+ Minimized display means we display the choices vertically (instead of optimized based on screen space).
+ An exception is made for options with images, where we always want to optimize screen space.
+ Numeric, date and datetime questions are also displayed "minimized", with a smaller screen width.-->
+ <t t-set="minimized_display" t-value="survey.questions_layout == 'page_per_question' and len(question.suggested_answer_ids) &lt;= 5 and not any(suggestion.value_image for suggestion in question.suggested_answer_ids)" />
+ <div t-if="survey.questions_layout == 'page_per_question'"
+ t-attf-class="o_survey_page_per_question o_survey_#{question.question_type} #{'o_survey_minimized_display' if minimized_display else ''}">
+ <input type="hidden" name="question_id" t-att-value="question.id" />
+ <!-- User has already answered for this session -->
+ <t t-if="answer.is_session_answer and (has_answered or answer.question_time_limit_reached)">
+ <fieldset disabled="disabled">
+ <t t-set="survey_form_readonly" t-value="True" />
+ <div class="mt-5">
+ <t t-call="survey.question_container" />
+ </div>
+ </fieldset>
+ <div t-if="answer.question_time_limit_reached and not has_answered" class="font-weight-bold">Sorry, you have not been fast enough.</div>
+ <div t-else="" class="font-weight-bold">We have registered your answer! Please wait for the host to go to the next question.</div>
+ </t>
+ <t t-elif="answer.is_session_answer and question.is_page and not is_html_empty(question.description)">
+ <div class="font-weight-bold mt-5">Pay attention to the host screen until the next question.</div>
+ </t>
+ <t t-else="">
+ <div class="mt-5">
+ <t t-call="survey.question_container"/>
+ </div>
+
+ <div class="row">
+ <div class="col-12 text-center mt16">
+ <button type="submit" t-att-value="'next' if not survey_last else 'finish'" class="btn btn-primary">
+ <t t-if="answer.is_session_answer or survey_last">Submit</t>
+ <t t-else="">Continue</t>
+ </button>
+ <span class="font-weight-bold text-muted ml-2 d-none d-md-inline">or press Enter</span>
+ </div>
+ </div>
+ </t>
+ </div>
+ </template>
+
+ <!-- Finished (taken and finished) survey page -->
+ <template id="survey_fill_form_done" name="Survey: finished">
+ <div class="wrap">
+ <div class="o_survey_finished mt32 mb32">
+ <h1>Thank you!</h1>
+ <div t-field="survey.description_done" class="oe_no_empty" />
+ <div class="row">
+ <div class="col">
+ <t t-if="survey.scoring_type != 'no_scoring' and survey.scoring_success_min">
+ <div>You scored <t t-esc="answer.scoring_percentage" />%</div>
+ <t t-if="answer.scoring_success">
+ <div>Congratulations, you have passed the test!</div>
+
+ <div t-if="survey.certification" class="mt16 mb16">
+ <a role="button"
+ class="btn btn-primary btn-lg"
+ t-att-href="'/survey/%s/get_certification' % survey.id">
+ <i class="fa fa-fw fa-trophy" role="img" aria-label="Download certification" title="Download certification"/>
+ Download certification
+ </a>
+ </div>
+ </t>
+ <t t-else="">
+ <div>Unfortunately, you have failed the test.</div>
+ </t>
+ </t>
+ <t t-call="survey.survey_button_retake"/>
+ <div t-if="survey.scoring_type != 'scoring_without_answers'">
+ If you wish, you can <a t-att-href="'/survey/print/%s?answer_token=%s&amp;review=True' % (survey.access_token, answer.access_token)">review your answers</a>
+ </div>
+ </div>
+ <div class="col-6 text-center" t-if="survey.certification_give_badge and answer.scoring_success">
+ <img t-att-src="'/web/image/gamification.badge/%s/image_128' % survey.certification_badge_id.id"/>
+ <div>You received the badge <span class="font-weight-bold" t-esc="survey.certification_badge_id.name"/>!</div>
+ </div>
+ </div>
+ </div>
+ <div class="container o_survey_result p-4" t-if="graph_data">
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane active survey_graph"
+ t-att-data-scoring_percentage="answer.scoring_percentage"
+ t-att-id="'survey_graph_question_%d' % answer.id"
+ t-att-data-question_id="answer.id"
+ data-graph-type="doughnut"
+ t-att-data-graph-data="graph_data">
+ <canvas id="doughnut_chart"></canvas>
+ <span class="o_overall_performance"></span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </template>
+
+ <!-- Question widgets -->
+ <template id="question_container" name="Survey: question container">
+ <t t-set="display_question"
+ t-value="survey.questions_layout == 'page_per_question'
+ or (survey.questions_layout == 'one_page' and not question.is_conditional)
+ or (survey.questions_layout == 'page_per_section' and (not question.is_conditional or triggering_answer_by_question[question.id] in selected_answers))"/>
+
+ <t t-set="answer_lines" t-value="answer.user_input_line_ids.filtered(lambda line: line.question_id == question)"/>
+ <!--Use Key selection if number of choices is < 26 to keep Z for other choice if any-->
+ <t t-set="letters" t-value="'ABCDEFGHIJKLMNOPQRSTUVWXYZ'"/>
+ <t t-set="useKeySelection" t-value="len(question.suggested_answer_ids) &lt; len(letters) and survey.questions_layout == 'page_per_question'"/>
+ <!-- Extra 'right' margin is added on layouts that are not "page_per_question" to align with choices questions, since all choices have a mr-2 class (pixel perfect yay...) -->
+ <t t-set="extra_right_margin" t-value="survey.questions_layout != 'page_per_question' and question.question_type not in ['simple_choice', 'multiple_choice']"/>
+ <div t-att-class="'js_question-wrapper pb-4 %s %s' % ('d-none' if not display_question else '', 'mr-2' if extra_right_margin else '')"
+ t-att-id="question.id" t-att-data-required="question.constr_mandatory"
+ t-att-data-constr-error-msg="question.constr_error_msg"
+ t-att-data-validation-error-msg="question.validation_error_msg">
+ <div class="mb-4">
+ <h3 t-if="not hide_question_title">
+ <span t-field='question.title' />
+ <span t-if="question.constr_mandatory" class="text-danger">*</span>
+ </h3>
+ <div t-if="not is_html_empty(question.description)" t-field='question.description' class="text-muted oe_no_empty mt-1"/>
+ </div>
+ <t t-if="question.question_type == 'text_box'"><t t-call="survey.question_text_box"/></t>
+ <t t-if="question.question_type == 'char_box'"><t t-call="survey.question_char_box"/></t>
+ <t t-if="question.question_type == 'numerical_box'"><t t-call="survey.question_numerical_box"/></t>
+ <t t-if="question.question_type == 'date'"><t t-call="survey.question_date"/></t>
+ <t t-if="question.question_type == 'datetime'"><t t-call="survey.question_datetime"/></t>
+ <t t-if="question.question_type == 'simple_choice'"><t t-call="survey.question_simple_choice"/></t>
+ <t t-if="question.question_type == 'multiple_choice'"><t t-call="survey.question_multiple_choice"/></t>
+ <t t-if="question.question_type == 'matrix'"><t t-call="survey.question_matrix"/></t>
+ <div class="o_survey_question_error overflow-hidden border-0 py-0 px-3 alert alert-danger" role="alert"></div>
+ </div>
+ </template>
+
+ <template id="question_text_box" name="Question: free text box">
+ <div class="o_survey_comment_container p-0">
+ <textarea class="form-control o_survey_question_text_box bg-transparent text-dark rounded-0 p-0" rows="3" t-att-name="question.id"
+ t-att-data-question-type="question.question_type"><t t-if="answer_lines" t-esc="answer_lines[0].value_text_box or None"/></textarea>
+ </div>
+ </template>
+
+ <template id="question_char_box" name="Question: text box">
+ <div class="o_survey_comment_container p-0">
+ <input t-att-type="'email' if question.validation_email else 'text'"
+ class="form-control o_survey_question_text_box bg-transparent text-dark rounded-0 p-0" t-att-name="question.id"
+ t-att-value="answer_lines[0].value_char_box if answer_lines else None"
+ t-att-data-question-type="question.question_type"
+ t-att-data-validation-length-min="question.validation_length_min if question.validation_required else False"
+ t-att-data-validation-length-max="question.validation_length_max if question.validation_required else False"/>
+ </div>
+ </template>
+
+ <template id="question_numerical_box" name="Question: numerical box">
+ <input type="number" step="any" class="form-control o_survey_question_numerical_box bg-transparent text-dark rounded-0 p-0"
+ t-att-name="question.id" t-att-value="answer_lines[0].value_numerical_box if answer_lines else None"
+ t-att-data-question-type="question.question_type"
+ t-att-data-validation-float-min="question.validation_min_float_value if question.validation_required else False"
+ t-att-data-validation-float-max="question.validation_max_float_value if question.validation_required else False"/>
+ </template>
+
+ <template id="question_date" name="Question: date box">
+ <div class="input-group o_survey_form_date" t-attf-id="datetimepicker_#{question.id}" data-target-input="nearest"
+ t-att-data-mindate="question.validation_min_date"
+ t-att-data-maxdate="question.validation_max_date">
+ <input type="text" class="form-control datetimepicker-input o_survey_question_date bg-transparent text-dark rounded-0 p-0"
+ t-attf-data-target="#datetimepicker_#{question.id}" t-att-name="question.id"
+ t-att-value="format_date(answer_lines[0].value_date) if answer_lines else None"
+ t-att-data-question-type="question.question_type"/>
+ <div t-if="not survey_form_readonly" class="input-group-append position-absolute" t-attf-data-target="#datetimepicker_#{question.id}" data-toggle="datetimepicker">
+ <div class="input-group-text text-primary border-0 bg-transparent p-0"><i class="fa fa-calendar"></i></div>
+ </div>
+ </div>
+ </template>
+
+ <template id="question_datetime" name="Question: datetime box">
+ <div class="input-group o_survey_form_date" t-attf-id="datetimepicker_#{question.id}" data-target-input="nearest"
+ t-att-data-mindate="question.validation_min_datetime"
+ t-att-data-maxdate="question.validation_max_datetime">
+ <input type="text" class="form-control datetimepicker-input o_survey_question_datetime bg-transparent text-dark rounded-0 p-0"
+ t-attf-data-target="#datetimepicker_#{question.id}" t-att-name="question.id"
+ t-att-value="format_datetime(answer_lines[0].value_datetime) if answer_lines else None"
+ t-att-data-question-type="question.question_type"/>
+ <div t-if="not survey_form_readonly" class="input-group-append position-absolute" t-attf-data-target="#datetimepicker_#{question.id}" data-toggle="datetimepicker">
+ <div class="input-group-text text-primary border-0 bg-transparent p-0"><i class="fa fa-calendar"></i></div>
+ </div>
+ </div>
+ </template>
+
+ <template id="question_suggested_value_image" name="Image from the question suggested answer">
+ <t t-if="question.allow_value_image and label.value_image">
+ <!-- Directly use field or route if the user doesn't have access rights -->
+ <div t-if="not env.user.has_group('survey.group_survey_user')"
+ class="d-flex my-3 justify-content-center">
+ <img t-att-src="'/survey/get_question_image/%s/%s/%s/%s' % (survey.access_token, answer.access_token, question.id, label.id)"/>
+ </div>
+ <div t-else="" t-field="label.value_image"
+ class="d-flex my-3 justify-content-center"
+ t-options="{'widget': 'image', 'alt-field': 'name', 'itemprop': 'image'}"/>
+ </t>
+ </template>
+
+ <template id="question_simple_choice" name="Question: simple choice">
+ <t t-set="answer_line" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id)"/>
+ <t t-set="comment_line" t-value="answer_lines.filtered(lambda line: line.value_char_box)"/>
+ <div class="row o_survey_form_choice"
+ t-att-data-name="question.id"
+ data-question-type="simple_choice_radio">
+ <t t-set="item_idx" t-value="0"/>
+ <div t-attf-class="col-lg-12 d-flex flex-wrap">
+ <t t-set="has_correct_answer" t-value="scoring_display_correction and any(label.is_correct for label in question.suggested_answer_ids)"/>
+ <t t-foreach='question.suggested_answer_ids' t-as='label'>
+ <t t-set="item_idx" t-value="label_index"/>
+ <t t-set="answer_selected" t-value="answer_line and answer_line.suggested_answer_id.id == label.id"/>
+ <t t-set="is_correct" t-value="label.answer_score > 0.0"/>
+
+ <!--Used for print mode with corrections -->
+ <t t-set="answer_class" t-if="not has_correct_answer" t-value="''" />
+ <t t-set="answer_class" t-elif="is_correct" t-value="'bg-success'" />
+ <t t-set="answer_class" t-elif="not is_correct" t-value="'bg-danger'" />
+
+ <label t-att-for="str(question.id) + '_' + str(label.id)"
+ t-att-class="'o_survey_choice_btn mr-2 mb-2 py-1 px-3 rounded %s %s' % (answer_class, 'o_survey_selected' if answer_selected else '')">
+ <t t-call="survey.survey_selection_key">
+ <t t-set="selection_key_class" t-value="'position-relative o_survey_radio_btn float-left d-flex'"/>
+ </t>
+ <span class="ml-2" t-field='label.value'/>
+ <input t-att-id="str(question.id) + '_' + str(label.id)" type="radio" t-att-value='label.id' class="o_survey_form_choice_item invisible position-absolute"
+ t-att-name='question.id'
+ t-att-checked="answer_line and answer_line.suggested_answer_id.id == label.id and 'checked' or None"
+ t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/>
+ <i class="fa fa-check-circle float-right mt-1 position-relative"></i>
+ <i class="fa fa-circle-thin float-right mt-1 position-relative"></i>
+ <t t-call="survey.question_suggested_value_image"/>
+ </label>
+ </t>
+ </div>
+ <div t-if='question.comments_allowed and question.comment_count_as_answer' class="js_comments col-lg-12" >
+ <div class="d-flex flex-wrap">
+ <label t-att-class="'o_survey_choice_btn mr-2 py-1 px-3 rounded %s' % ('o_survey_selected' if comment_line else '')">
+ <t t-set="item_idx" t-value="item_idx + 1"/>
+ <t t-call="survey.survey_selection_key">
+ <t t-set="selection_key_class" t-value="'position-relative o_survey_radio_btn float-left d-flex'"/>
+ </t>
+ <input type="radio" class="o_survey_form_choice_item o_survey_js_form_other_comment invisible position-absolute" value="-1"
+ t-att-name='question.id'
+ t-att-checked="comment_line and 'checked' or None"
+ t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/>
+ <span class="ml-2" t-field="question.comments_message" />
+ <i class="fa fa-check-circle float-right mt-1 position-relative"></i>
+ <i class="fa fa-circle-thin float-right mt-1 position-relative"></i>
+ </label>
+ </div>
+ <div t-attf-class="o_survey_comment_container mt-3 py-0 px-1 #{'d-none' if not comment_line else ''}">
+ <textarea type="text" class="form-control o_survey_question_text_box bg-transparent text-dark rounded-0 p-0"
+ t-att-disabled="None if comment_line else 'disabled'"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
+ </div>
+ </div>
+ <div t-if='question.comments_allowed and not question.comment_count_as_answer' class="col-lg-12 o_survey_comment_container mx-1 mt-3 pl-3 pr-4">
+ <textarea type="text" class="form-control o_survey_comment o_survey_question_text_box bg-transparent text-dark rounded-0 p-0"
+ t-att-placeholder="question.comments_message if not survey_form_readonly else ''"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
+ </div>
+ </div>
+ </template>
+
+ <template id="question_multiple_choice" name="Question: multiple choice">
+ <t t-set="comment_line" t-value="answer_lines.filtered(lambda line: line.value_char_box)"/>
+ <div class="row o_survey_form_choice o_survey_question_multiple_choice"
+ t-att-data-name="question.id"
+ t-att-data-question-type="question.question_type">
+ <t t-set="item_idx" t-value="0"/>
+ <div class="d-flex flex-wrap col-lg-12">
+ <t t-set="has_correct_answer" t-value="scoring_display_correction and any(label.is_correct for label in question.suggested_answer_ids)"/>
+ <t t-foreach='question.suggested_answer_ids' t-as='label'>
+ <t t-set="item_idx" t-value="label_index"/>
+ <t t-set="answer_line" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id == label)"/>
+ <t t-set="answer_selected" t-value="answer_line and answer_line.suggested_answer_id.id == label.id"/>
+ <t t-set="is_correct" t-value="label.answer_score > 0.0"/>
+
+ <!--Used for print mode with corrections -->
+ <t t-set="answer_class" t-if="not has_correct_answer" t-value="''" />
+ <t t-set="answer_class" t-elif="is_correct" t-value="'bg-success'" />
+ <t t-set="answer_class" t-elif="not is_correct" t-value="'bg-danger'" />
+
+ <label t-att-class="'o_survey_choice_btn mr-2 py-1 px-3 rounded %s %s' % (answer_class, 'o_survey_selected' if answer_line else '')">
+ <t t-call="survey.survey_selection_key">
+ <t t-set="selection_key_class" t-value="'position-relative float-left d-flex'"/>
+ </t>
+ <input type="checkbox" t-att-value='label.id' class="o_survey_form_choice_item invisible position-absolute"
+ t-att-name="question.id"
+ t-att-checked="'checked' if answer_line else None"
+ t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/>
+ <span class="ml-2" t-field='label.value'/>
+ <i class="fa fa-check-square float-right mt-1 position-relative"></i>
+ <i class="fa fa-square-o float-right mt-1 position-relative"></i>
+ <t t-call="survey.question_suggested_value_image"/>
+ </label>
+ </t>
+ </div>
+ <div t-if='question.comments_allowed and question.comment_count_as_answer' class="js_ck_comments col-lg-12" >
+ <div class="d-flex flex-wrap">
+ <label t-att-class="'o_survey_choice_btn mr-2 py-1 px-3 rounded %s' % ('o_survey_selected' if comment_line else '')">
+ <t t-set="item_idx" t-value="item_idx + 1"/>
+ <t t-call="survey.survey_selection_key">
+ <t t-set="selection_key_class" t-value="'position-relative float-left d-flex'"/>
+ </t>
+ <input type="checkbox" class="o_survey_form_choice_item o_survey_js_form_other_comment invisible position-absolute" value="-1"
+ t-att-name="question.id"
+ t-att-checked="comment_line and 'checked' or None"
+ t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"/>
+ <span class="ml-2" t-field="question.comments_message" />
+ <i class="fa fa-check-square float-right mt-1 position-relative"></i>
+ <i class="fa fa-square-o float-right mt-1 position-relative"></i>
+ </label>
+ </div>
+ <div t-attf-class="o_survey_comment_container mt-3 py-0 px-1 #{'d-none' if not comment_line else ''}">
+ <textarea type="text" class="form-control o_survey_question_text_box bg-transparent text-dark rounded-0 p-0"
+ t-att-disabled="None if comment_line else 'disabled'"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
+ </div>
+ </div>
+ <div t-if='question.comments_allowed and not question.comment_count_as_answer' class="col-lg-12 o_survey_comment_container mx-1 mt-3 py-0 pl-3 pr-4">
+ <textarea type="text" class="form-control o_survey_comment o_survey_question_text_box bg-transparent text-dark rounded-0 p-0"
+ t-att-placeholder="question.comments_message if not survey_form_readonly else ''"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
+ </div>
+ </div>
+ </template>
+
+ <template id="question_matrix" name="Question: matrix">
+ <t t-set="comment_line" t-value="answer_lines.filtered(lambda line: line.value_char_box)"/>
+ <table class="table table-hover o_survey_question_matrix text-white text-center mb-0"
+ t-att-data-name="question.id"
+ t-att-data-question-type="question.question_type"
+ t-att-data-sub-questions="question.matrix_row_ids.ids">
+ <thead>
+ <tr>
+ <th class="border-0"> </th>
+ <th class="border-0 font-weight-normal" t-foreach="question.suggested_answer_ids" t-as="col_label"><span t-field="col_label.value" /></th>
+ </tr>
+ </thead>
+ <tbody>
+ <t t-set="item_idx" t-value="0"/>
+ <!-- For matrix, we have an extra check because we have rows * columns total options -->
+ <t t-set="useKeySelection" t-value="useKeySelection and (len(question.suggested_answer_ids) * len(question.matrix_row_ids)) &lt; len(letters)" />
+ <tr class="bg-white text-white" t-foreach="question.matrix_row_ids" t-as="row_label" t-att-id="row_label.id">
+ <th class="border-0 font-weight-normal text-left"><span t-field="row_label.value" /></th>
+ <t t-foreach="question.suggested_answer_ids" t-as="col_label">
+ <t t-set="answer" t-value="answer_lines.filtered(lambda line: line.suggested_answer_id == col_label and line.matrix_row_id == row_label)"/>
+ <td t-att-class="'o_survey_matrix_btn text-primary border-0 position-relative %s'
+ % ('o_survey_selected' if answer else '')">
+ <input t-att-type="'checkbox' if question.matrix_subtype == 'multiple' else 'radio'"
+ t-att-name="'%s_%s' % (question.id, row_label.id)" t-att-value='col_label.id'
+ t-att-checked="'checked' if answer else None"
+ t-att-data-row-id="row_label.id"
+ t-att-data-selection-key="letters[item_idx] if useKeySelection else ''"
+ class="o_survey_form_choice_item d-none"/>
+ <i t-att-class="'o_survey_matrix_empty_checkbox fa fa-%s position-relative'
+ % ('square-o' if question.matrix_subtype == 'multiple' else 'circle-thin')"></i>
+ <i t-att-class="'fa fa-%s position-relative'
+ % ('check-square' if question.matrix_subtype == 'multiple' else 'check-circle')"></i>
+ <t t-call="survey.survey_selection_key">
+ <t t-set="selection_key_class"
+ t-value="'position-absolute float-right font-weight-bold %s' % ('o_survey_radio_btn' if question.matrix_subtype != 'multiple' else '')"/>
+ </t>
+ <t t-set="item_idx" t-value="item_idx + 1"/>
+ </td>
+ </t>
+ </tr>
+ </tbody>
+ </table>
+ <div t-if='question.comments_allowed'>
+ <textarea type="text" class="form-control o_survey_question_text_box o_survey_comment bg-transparent text-dark rounded-0 p-0 mt-3"
+ t-att-placeholder="question.comments_message if not survey_form_readonly else ''"
+ t-att-name="'%s_%s' % (question.id, 'comment')"><t t-esc="comment_line.value_char_box if comment_line else ''"/></textarea>
+ </div>
+ </template>
+
+ <template id="survey_selection_key">
+ <div t-if="useKeySelection" t-att-class="'o_survey_choice_key bg-white rounded %s' % selection_key_class">
+ <span class="o_survey_key text-center position-absolute bg-white rounded-left py-0 pl-2"><span class="text-primary text-center text-center w-100 position-relative">Key</span></span>
+ <span class="text-primary text-center w-100 position-relative" t-esc="letters[item_idx]"/>
+ </div>
+ </template>
+
+ <template id="survey_progression" name="Survey: Progression">
+ <t t-if="len(page_ids) > 1 and not survey.has_conditional_questions">
+ <t t-set="percentage" t-value="round(100*(page_number/len(page_ids)))"/>
+ <t t-if="survey.progression_mode == 'percent'">
+ <span class="o_survey_progress_percent" t-esc="percentage"/> % completed
+ </t>
+ <t t-else="">
+ <span class="o_survey_progress_number" t-esc="page_number"/> of <span t-esc="len(page_ids)"/>
+ <span t-if="survey.questions_layout == 'page_per_question'">answered</span>
+ <span t-else="">pages</span>
+ </t>
+ <div class="o_survey_progress progress flex-grow-1">
+ <div class="progress-bar bg-primary" t-att-style="'width: ' + str(percentage) + '%'"/>
+ </div>
+ </t>
+ </template>
+</data>
+</odoo>
diff --git a/addons/survey/views/survey_templates_management.xml b/addons/survey/views/survey_templates_management.xml
new file mode 100644
index 00000000..4612b6c0
--- /dev/null
+++ b/addons/survey/views/survey_templates_management.xml
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo><data>
+
+ <!-- ============================================================ -->
+ <!-- Errors / Corner case management -->
+ <!-- ============================================================ -->
+
+ <!-- Forbidden error messages-->
+ <template id="survey_403_page" name="Survey: custom 403 page">
+ <t t-call="survey.layout">
+ <div id="wrap">
+ <div class="container">
+ <h1 class="mt32">403: Forbidden</h1>
+ <p>The page you were looking for could not be authorized.</p>
+ <p>Maybe you were looking for
+ <a t-attf-href="/web#view_type=form&amp;model=survey.survey&amp;id=#{survey.id}&amp;action=survey.action_survey_form">this page</a> ?
+ </p>
+ </div>
+ </div>
+ </t>
+ </template>
+
+ <!-- Error: void survey -->
+ <template id="survey_void_content" name="Survey: void content">
+ <t t-call="survey.layout">
+ <t t-if="answer.test_entry" t-call="survey.survey_button_form_view" />
+ <div class="wrap">
+ <div class="container">
+ <div class="jumbotron mt32">
+ <h1><span t-field="survey.title"/> survey is void</h1>
+ <p>Please make sure you have at least one question in your survey. You also need at least one section if you chose the "Page per section" layout.<br />
+ <a t-att-href="'/web#view_type=form&amp;model=survey.survey&amp;id=%s&amp;action=survey.action_survey_form' % survey.id"
+ class="btn btn-secondary"
+ groups="survey.group_survey_manager">Edit in backend</a>
+ </p>
+ </div>
+ </div>
+ </div>
+ </t>
+ </template>
+
+ <!-- Error: auth required -->
+ <template id="survey_auth_required" name="Survey: login required">
+ <t t-call="survey.layout">
+ <div class="wrap">
+ <div class="container">
+ <div class="jumbotron mt32">
+ <h1>Login required</h1>
+ <p>This survey is open only to registered people. Please
+ <a t-att-href="redirect_url">log in</a>.
+ </p>
+ </div>
+ </div>
+ </div>
+ </t>
+ </template>
+
+ <!-- Expired (closed) survey page -->
+ <template id="survey_closed_expired" name="Survey: expired">
+ <t t-call="survey.layout">
+ <div class="wrap">
+ <div class="container">
+ <div class="jumbotron mt32">
+ <h1><span t-field="survey.title"/> survey expired</h1>
+ <p>This survey is now closed. Thank you for your interest !</p>
+ </div>
+ </div>
+ </div>
+ </t>
+ </template>
+
+ <!-- ============================================================ -->
+ <!-- Tools / Utilities -->
+ <!-- ============================================================ -->
+
+ <template id="survey_button_form_view" name="Survey: back to form view">
+ <div groups="survey.group_survey_manager" t-ignore="true" class="alert alert-info alert-dismissible rounded-0 fade show d-print-none css_editable_mode_hidden mb-0">
+ <div t-ignore="true" class="text-center">
+ <a t-attf-href="/web#view_type=form&amp;model=survey.survey&amp;id=#{survey.id}&amp;action=survey.action_survey_form"><i class="fa fa-fw fa-arrow-right"/><span t-if="answer and answer.test_entry">This is a test survey. </span>Edit Survey</a>
+ </div>
+ <button type="button" class="close" data-dismiss="alert" aria-label="Close"> &#215; </button>
+ </div>
+ </template>
+
+ <template id="survey_button_retake" name="Survey: retake button">
+ <div>
+ <t t-if="not answer.scoring_success and not answer.is_session_answer">
+ <t t-if="survey.is_attempts_limited">
+ <t t-set="attempts_left" t-value="survey._get_number_of_attempts_lefts(answer.partner_id, answer.email, answer.invite_token)" />
+ <t t-if="attempts_left > 0">
+ <p><span>Number of attemps left</span>: <span t-esc="attempts_left"></span></p>
+ <p><a role="button" class="btn btn-primary btn-lg" t-att-href="'/survey/retry/%s/%s' % (survey.access_token, answer.access_token)">
+ Retry</a></p>
+ </t>
+ </t>
+ <t t-else="">
+ <p><a role="button" class="btn btn-primary btn-lg" t-att-href="'/survey/retry/%s/%s' % (survey.access_token, answer.access_token)">
+ Retry</a></p>
+ </t>
+ </t>
+ </div>
+ </template>
+
+ <!-- Survey Home page - Session Code
+ Used in 'session mode' to give an easy access to the survey through the '/s' route. -->
+ <template id="survey_session_code" name="Survey: Access Code page">
+ <t t-call="survey.layout">
+ <div class="wrap o_survey_wrap pb16 d-flex">
+ <div class="container o_survey_quick_access d-flex flex-column">
+ <div class="d-flex flex-grow-1 align-items-center">
+ <div class="col-lg-12">
+ <div class="text-center mb32">
+ <h3>Please enter the code</h3>
+ </div>
+ <div class="row">
+ <div class="offset-md-4 col-md-4 text-center">
+ <input id="session_code" type="text" placeholder="4812"
+ class="form-control o_survey_question_text_box font-weight-bold bg-transparent text-primary text-center rounded-0 p-2 w-100"/>
+ </div>
+ <div class="col-3 text-center o_survey_error text-danger d-none pt-2" role="alert">
+ <span>Code is incorrect. Please try again.</span>
+ </div>
+ </div>
+ <div class="text-center mt32 p-2">
+ <button type="submit" class="btn btn-primary">Submit</button>
+ </div>
+ <div class="text-center p-2">
+ <span class="text-muted">The code is found on the screen in front of you</span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </t>
+ </template>
+
+ <template id="survey_navigation" name="Survey: Navigation">
+ <button t-if="can_go_back"
+ type="submit" class="btn p-0 shadow-none o_survey_navigation_submit" name="button_submit" value="previous" t-att-data-previous-page-id="previous_page_id">
+ <i class="border-left fa fa-chevron-left p-2" />
+ </button>
+ <button t-if="survey and survey.questions_layout in ['page_per_question', 'page_per_section'] and answer and answer.state != 'done' and not answer.is_session_answer"
+ type="submit" class="btn p-0 shadow-none o_survey_navigation_submit" t-att-value="'next' if not survey_last else 'finish'">
+ <i class="border-left fa fa-chevron-right p-2" />
+ </button>
+ </template>
+
+</data>
+</odoo>
diff --git a/addons/survey/views/survey_templates_print.xml b/addons/survey/views/survey_templates_print.xml
new file mode 100644
index 00000000..a1f27ecb
--- /dev/null
+++ b/addons/survey/views/survey_templates_print.xml
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+ <!-- Survey: printable page view (all pages) -->
+ <template id="survey_page_print" name="Survey: print page">
+ <t t-call="survey.layout">
+ <t t-set="survey_form_readonly" t-value="true"/>
+ <t t-if="answer.test_entry" t-call="survey.survey_button_form_view" />
+ <div class="wrap">
+ <div class="o_survey_print container">
+ <div class='py-5 mt32'>
+ <h1><span t-field='survey.title'/></h1>
+ <t t-if="survey.description"><div t-field='survey.description' class="oe_no_empty"/></t>
+ <t t-if="review" t-call="survey.survey_button_retake"/>
+ </div>
+ <div role="form">
+ <fieldset disabled="disabled">
+ <t t-foreach='survey.question_and_page_ids' t-as='question'>
+ <t t-if="question.is_page and
+ (any(q in questions_to_display for q in question.question_ids)
+ or not is_html_empty(question.description))">
+ <hr t-if="question != survey.page_ids[0]" />
+ <div class="o_page_header">
+ <h1 t-field='question.title' />
+ <div t-if="question.description" t-field='question.description' class="oe_no_empty"/>
+ </div>
+ </t>
+ <t t-if="not question.is_page and not answer or (question in answer.predefined_question_ids &amp; questions_to_display)" >
+ <t t-set="answer_lines" t-value="answer.user_input_line_ids.filtered(lambda line: line.question_id == question)"/>
+ <div class="js_question-wrapper" t-att-id="question.id">
+ <h2>
+ <span t-field='question.title'/>
+ <span t-if="question.constr_mandatory" class="text-danger">*</span>
+ <span t-if="scoring_display_correction" class="badge badge-pill" t-att-data-score-question="question.id"></span>
+ </h2>
+ <t t-if="question.description"><div class="text-muted oe_no_empty" t-field='question.description'/></t>
+ <t t-if="question.question_type == 'text_box'"><t t-call="survey.question_text_box"/></t>
+ <t t-if="question.question_type == 'char_box'"><t t-call="survey.question_char_box"/></t>
+ <t t-if="question.question_type == 'numerical_box'"><t t-call="survey.question_numerical_box"/></t>
+ <t t-if="question.question_type == 'date'"><t t-call="survey.question_date"/></t>
+ <t t-if="question.question_type == 'datetime'"><t t-call="survey.question_datetime"/></t>
+ <t t-if="question.question_type == 'simple_choice'"><t t-call="survey.question_simple_choice"/></t>
+ <t t-if="question.question_type == 'multiple_choice'"><t t-call="survey.question_multiple_choice"/></t>
+ <t t-if="question.question_type == 'matrix'"><t t-call="survey.question_matrix"/></t>
+ <div class="o_survey_question_error overflow-hidden border-0 py-0 px-3 alert alert-danger" role="alert"></div>
+ </div>
+ </t>
+ </t>
+ </fieldset>
+ </div>
+ </div>
+ </div>
+ </t>
+ </template>
+</data>
+</odoo>
diff --git a/addons/survey/views/survey_templates_statistics.xml b/addons/survey/views/survey_templates_statistics.xml
new file mode 100644
index 00000000..20de2dd7
--- /dev/null
+++ b/addons/survey/views/survey_templates_statistics.xml
@@ -0,0 +1,422 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+ <template id="survey_page_statistics" name="Survey: result statistics page">
+ <t t-call="survey.layout">
+ <t t-call="survey.survey_button_form_view" />
+ <t t-set="page_record_limit" t-value="10"/><!-- Change this record_limit to change number of record per page-->
+ <div class="container o_survey_result">
+ <t t-call="survey.survey_page_statistics_header" />
+ <t t-call="survey.survey_page_statistics_inner" />
+ </div>
+ </t>
+ </template>
+
+ <template id="survey_page_statistics_header" name="Survey: result statistics header">
+ <div class="py-5 mt32">
+ <h1>
+ <span t-field="survey.title"/>
+ <span style="font-size:1.5em;"
+ t-attf-class="fa fa-bar-chart-o #{'fa-bar-chart-o' if survey.scoring_type == 'no_scoring' else 'fa-trophy' if survey.certification else 'fa-question-circle-o'} float-right " role="img" aria-label="Chart" title="Chart"/>
+ </h1>
+ <div t-field="survey.description" class="oe_no_empty"/>
+ <h2 t-if="not question_and_page_data">
+ Sorry, no one answered this survey yet.
+ </h2>
+ </div>
+ </template>
+
+ <template id="survey_page_statistics_inner" name="Survey: result statistics content">
+ <div t-if="survey.session_show_leaderboard" class="o_survey_session_leaderboard mb-5 mt-1">
+ <h2 class="mt16 text-uppercase text-muted">Leaderboard</h2>
+ <t t-call="survey.user_input_session_leaderboard" />
+ </div>
+ <div t-if="question_and_page_data" class="card d-print-none">
+ <div class="card-header"><span class="fa fa-filter"></span> Filters <span t-if="search_filters" class="float-right text-primary clear_survey_filter"><i class="fa fa-times"></i> Clear All Filters</span></div>
+ <div class="card-body">
+ <span t-att-class="'badge only_left_radius filter-all %s' % 'badge-secondary' if search_finished else 'badge-primary o_active_filter'">All surveys</span>
+ <span t-att-class="'badge only_right_radius filter-finished %s' % 'badge-secondary' if not search_finished else 'badge-primary o_active_filter'">Finished surveys</span>
+ <span t-foreach="search_filters" t-as="filter_data">
+ <span class="badge badge-primary only_left_radius"><i class="fa fa-filter" role="img" aria-label="Filter" title="Filter"></i></span><span class="badge badge-primary no_radius" t-esc="filter_data['question']"></span><span class="badge badge-success only_right_radius" t-esc="' > '.join(filter_data['answers'])"></span>
+ </span>
+ </div>
+ </div>
+ <div t-if="survey.scoring_type in ['scoring_with_answers', 'scoring_without_answers']">
+ <h2 class="mt16 text-uppercase text-muted">Results Overview</h2>
+ <div>Success rate: <mark class="font-weight-bold"><t t-esc="survey_data['global_success_rate']"></t>%</mark></div>
+ <div class="survey_graph" data-graph-type="pie" t-att-data-graph-data="survey_data['global_success_graph']">
+ <!-- canvas element for drawing pie chart -->
+ <canvas/>
+ </div>
+ <hr/>
+ </div>
+
+ <div t-foreach="question_and_page_data" t-as='question_data'>
+ <t t-set="question" t-value="question_data['question']"/>
+ <t t-if="question_data['is_page']">
+ <h2 class="mt16 text-uppercase text-muted" t-field="question.title"/>
+ <div t-field="question.description" class="oe_no_empty" />
+ <hr class="mt-2 pb-1 mb-1"/>
+ </t>
+ <div t-else="" class="ml-4 mt-4">
+ <t t-call="survey.survey_page_statistics_question" />
+ </div>
+ </div>
+ </template>
+
+ <template id="survey_page_statistics_question" name="Question: result statistics">
+ <t t-set="question_scoring" t-value="survey.scoring_type in ['scoring_with_answers', 'scoring_without_answers']"/>
+ <t t-set="comment_lines" t-value="question_data['comment_line_ids']"/>
+ <t t-set="graph_data" t-value="question_data['graph_data']"/>
+ <t t-set="table_data" t-value="question_data['table_data']"/>
+
+ <div>
+ <div class="d-flex align-items-start mb-2">
+ <div class="mr-auto">
+ <h5 t-field="question.title" class="mb-1"/>
+ <div t-if="question_scoring">
+ <t t-if="question.question_type in ['simple_choice', 'multiple_choice']">
+ <t t-if="len(question_data['right_answers']) >= 1">
+ <span t-if="len(question_data['right_answers']) == 1">Right answer: </span>
+ <span t-if="len(question_data['right_answers']) > 1">Right answers: </span>
+ <strong>
+ <t t-foreach="question_data['right_answers']" t-as="answer">
+ <span t-if="answer_index != 0">, </span><span t-esc="answer.value"/>
+ </t>
+ </strong>
+ </t>
+ </t>
+ <t t-elif="question.is_scored_question">
+ <span>Right answer:</span>
+ <strong>
+ <t t-if="question.question_type == 'numerical_box'">
+ <span t-esc="question.answer_numerical_box"/>
+ </t>
+ <t t-if="question.question_type == 'date'">
+ <span t-field="question.answer_date"/>
+ </t>
+ <t t-if="question.question_type == 'datetime'">
+ <span t-field="question.answer_datetime"/>
+ </t>
+ </strong><br/>
+ <span>Score:</span>
+ <strong>
+ <span t-esc="question.answer_score"/>
+ </strong>
+ </t>
+ </div>
+ </div>
+ <!-- Question info -->
+ <span class="badge badge-info" t-field='question.question_type'/>
+ <t t-if="question.question_type == 'matrix'">
+ <span class="badge badge-info ml-2" t-field='question.matrix_subtype'/>
+ </t>
+ <!-- Scoring info -->
+ <t t-if="question_scoring">
+ <t t-if="question.question_type in ['simple_choice', 'multiple_choice']">
+ <span class="badge badge-success ml-3"><span t-esc="question_data['right_inputs_count']"></span> Correct</span>
+ <span class="badge badge-warning ml-1" t-if="question.question_type == 'multiple_choice'">
+ <span t-esc="question_data['partial_inputs_count']"></span> Partial
+ </span>
+ </t>
+ <t t-if="question.is_scored_question">
+ <span class="badge badge-success ml-3"><span t-esc="question_data['right_inputs_count']"></span> Correct</span>
+ </t>
+ </t>
+ <!-- Inputs info -->
+ <span class="badge badge-info ml-3"><span t-esc="len(question_data['answer_input_done_ids'])"></span> Answered</span>
+ <span class="badge badge-info ml-1"><span t-esc="len(question_data['answer_input_skipped_ids'])"></span> Skipped</span>
+ </div>
+
+ <!-- Question Description -->
+ <div class="ml-3 text-muted" t-field="question.description"/>
+ <t t-if="question.question_type in ['text_box', 'char_box', 'datetime']">
+ <t t-call="survey.question_result_text"/>
+ </t>
+ <t t-elif="question.question_type in ['numerical_box', 'date']">
+ <t t-call="survey.question_result_number_or_date"></t>
+ </t>
+ <t t-elif="question.question_type in ['simple_choice', 'multiple_choice']">
+ <t t-call="survey.question_result_choice"></t>
+ </t>
+ <t t-elif="question.question_type in ['matrix']">
+ <t t-call="survey.question_result_matrix"></t>
+ </t>
+ </div>
+ </template>
+
+ <template id="question_result_text" name="Question: text result (text_box, char_box, datetime)">
+ <table class="table table-hover table-sm" t-att-id="'survey_table_question_%d' % question.id">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>User Responses</th>
+ </tr>
+ </thead>
+ <tbody>
+ <t t-foreach="table_data" t-as="input_line">
+ <tr t-if="not input_line.skipped" t-att-class="'d-none' if input_line_index >= page_record_limit else ''">
+ <td>
+ <t t-if="no_print_url"><t t-esc="input_line_index + 1"></t></t>
+ <t t-else="">
+ <a t-att-href="input_line.user_input_id.get_print_url()">
+ <t t-esc="input_line_index + 1"></t>
+ </a>
+ </t>
+ </td>
+ <td>
+ <t t-if="question.question_type == 'text_box'">
+ <span t-if="no_print_url" t-field="input_line.value_text_box" />
+ <a t-else="" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_text_box"></a>
+ </t>
+ <t t-if="question.question_type == 'char_box'">
+ <span t-if="no_print_url" t-field="input_line.value_char_box" />
+ <a t-else="" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_char_box"></a>
+ </t>
+ <t t-if="question.question_type == 'datetime'">
+ <span t-if="no_print_url" t-field="input_line.value_datetime" />
+ <a t-else="" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_datetime"></a>
+ </t>
+ </td>
+ </tr>
+ </t>
+ </tbody>
+ </table>
+ <t t-call="survey.question_table_pagination"/>
+ </template>
+
+ <template id="question_result_number_or_date" name="Question: number or date result (numerical_box or date)">
+ <t t-if="question.question_type == 'numerical_box'">
+ <span class="float-right mt8">
+ <span class="badge badge-secondary only_left_radius">Maximum </span> <span class="badge badge-success only_right_radius" t-esc="question_data['numerical_max']"></span>
+ <span class="badge badge-secondary only_left_radius">Minimum </span> <span class="badge badge-danger only_right_radius" t-esc="question_data['numerical_min']"></span>
+ <span class="badge badge-secondary only_left_radius">Average </span> <span class="badge badge-warning only_right_radius" t-esc="question_data['numerical_average']"></span>
+ </span>
+ </t>
+
+ <ul class="nav nav-tabs d-print-none" role="tablist">
+ <li class="nav-item">
+ <a t-att-href="'#survey_stats_question_%d' % question.id"
+ t-att-aria-controls="'survey_stats_question_%d' % question.id"
+ class="nav-link active" data-toggle="tab" role="tab">
+ <i class="fa fa-list-ol"></i> Most Common
+ </a>
+ </li>
+ <li class="nav-item">
+ <a t-att-href="'#survey_data_question_%d' % question.id"
+ t-att-aria-controls="'survey_data_question_%d' % question.id"
+ class="nav-link" data-toggle="tab" role="tab">
+ <i class="fa fa-list-alt"></i> All Data
+ </a>
+ </li>
+ </ul>
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane active with-3d-shadow with-transitions" t-att-id="'survey_stats_question_%d' % question.id">
+ <table class="table table-hover table-sm">
+ <thead>
+ <tr>
+ <th>User Responses</th>
+ <th>Occurrence</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr t-foreach="question_data['common_lines']" t-as="common_line">
+ <td>
+ <span t-if="question.question_type == 'numerical_box'" t-esc="common_line[0]"/>
+ <span t-if="question.question_type == 'date'" t-esc="common_line[0]" t-options='{"widget": "date"}'/>
+ </td>
+ <td><span t-esc="common_line[1]"></span></td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div role="tabpanel" class="tab-pane" t-att-id="'survey_data_question_%d' % question.id">
+ <table class="table table-hover table-sm" t-att-id="'survey_table_question_%d' % question.id">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>User Responses</th>
+ </tr>
+ </thead>
+ <tbody>
+ <t t-foreach="table_data" t-as="input_line">
+ <tr t-if="not input_line.skipped" t-att-class="'d-none' if input_line_index >= page_record_limit else ''">
+ <td>
+ <t t-if="no_print_url"><t t-esc="input_line_index + 1"></t></t>
+ <t t-else="">
+ <a t-att-href="input_line.user_input_id.get_print_url()">
+ <t t-esc="input_line_index + 1"></t>
+ </a>
+ </t>
+ </td>
+ <td>
+ <a t-if="question.question_type == 'numerical_box'" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_numerical_box"/>
+ <a t-if="question.question_type == 'date'" t-att-href="input_line.user_input_id.get_print_url()" t-field="input_line.value_date"/>
+ </td>
+ </tr>
+ </t>
+ </tbody>
+ </table>
+ <t t-call="survey.question_table_pagination"/>
+ </div>
+ </div>
+ </template>
+
+ <template id="question_result_choice" name="Question: choice result (simple_choice, multiple_choice)">
+ <ul class="nav nav-tabs d-print-none" role="tablist">
+ <li class="nav-item">
+ <a t-att-href="'#survey_graph_question_%d' % question.id"
+ t-att-aria-controls="'survey_graph_question_%d' % question.id"
+ class="nav-link active" data-toggle="tab" role="tab">
+ <i class="fa fa-bar-chart-o"></i>
+ <span t-if="question.question_type == 'simple_choice'">Pie Graph</span>
+ <span t-else="">Graph</span>
+ </a>
+ </li>
+ <li class="nav-item">
+ <a t-att-href="'#survey_data_question_%d' % question.id"
+ t-att-aria-controls="'survey_data_question_%d' % question.id"
+ class="nav-link" data-toggle="tab" role="tab">
+ <i class="fa fa-list-alt"></i> Data
+ </a>
+ </li>
+ </ul>
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane active survey_graph"
+ t-att-id="'survey_graph_question_%d' % question.id"
+ t-att-data-question_id="question.id"
+ t-att-data-graph-type="'pie' if question.question_type == 'simple_choice' else 'bar'"
+ t-att-data-graph-data="graph_data">
+ <!-- canvas element for drawing bar chart -->
+ <canvas/>
+ </div>
+ <div role="tabpanel" class="tab-pane" t-att-id="'survey_data_question_%d' % question.id">
+ <table class="table table-hover table-sm">
+ <thead>
+ <tr>
+ <th>Answer</th>
+ <th>User Choice</th>
+ <th t-if="question_scoring">Score</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr t-foreach="table_data" t-as="choice_data">
+ <td>
+ <p t-esc="choice_data['value']"></p>
+ </td>
+ <td class="survey_answer">
+ <span t-esc="round(choice_data['count'] * 100.0/ (len(question_data['answer_line_done_ids']) or 1), 2)"></span> %
+ <span t-esc="'%s Votes' % choice_data['count']" class="badge badge-primary"/>
+ <i t-if="choice_data['suggested_answer'].id"
+ class="fa fa-filter text-primary survey_filter"
+ t-att-data-question_id="question.id"
+ t-att-data-answer_id="choice_data['suggested_answer'].id"
+ role="img" aria-label="Filter question" title="Filter question"/>
+ </td>
+ <td t-if="question_scoring" t-esc="choice_data['suggested_answer'].answer_score"/>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <div t-if="comment_lines" t-call="survey.question_result_comments" />
+ </template>
+
+ <template id="question_result_matrix" name="Question: matrix result (matrix)">
+ <t t-set="graph_data" t-value="question_data['graph_data']"/>
+ <t t-set="table_data" t-value="question_data['table_data']"/>
+ <ul class="nav nav-tabs d-print-none" role="tablist">
+ <li class="nav-item">
+ <a t-att-href="'#survey_graph_question_%d' % question.id"
+ t-att-aria-controls="'survey_graph_question_%d' % question.id"
+ class="nav-link active" data-toggle="tab" role="tab">
+ <i class="fa fa-bar-chart"></i> Graph
+ </a>
+ </li>
+ <li class="nav-item">
+ <a t-att-href="'#survey_data_question_%d' % question.id"
+ t-att-aria-controls="'survey_data_question_%d' % question.id"
+ class="nav-link" data-toggle="tab" role="tab">
+ <i class="fa fa-list-alt"></i> Data
+ </a>
+ </li>
+ </ul>
+ <div class="tab-content">
+ <div role="tabpanel" class="tab-pane active with-3d-shadow with-transitions survey_graph"
+ t-att-id="'survey_graph_question_%d' % question.id"
+ t-att-data-question_id= "question.id"
+ data-graph-type= "multi_bar"
+ t-att-data-graph-data="graph_data">
+ <!-- canvas element for drawing Multibar chart -->
+ <canvas/>
+ </div>
+ <div role="tabpanel" class="tab-pane" t-att-id="'survey_data_question_%d' % question.id">
+ <table class="table table-hover table-sm text-right">
+ <thead>
+ <tr>
+ <th></th>
+ <th class="text-right" t-foreach="table_data[0]['columns']" t-as="column_data">
+ <span t-esc="column_data['suggested_answer'].value"></span>
+ </th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr t-foreach="table_data" t-as="choice_data">
+ <td>
+ <span t-esc="choice_data['row'].value"></span>
+ </td>
+ <td class="survey_answer" t-foreach="choice_data['columns']" t-as="column_data">
+ <span t-esc="round(column_data['count'] * 100.0/ (len(question_data['answer_line_done_ids']) or 1), 2)"></span> %
+ <span class="badge badge-primary" t-esc="column_data['count']"></span>
+ <i class="fa fa-filter text-primary survey_filter"
+ t-att-data-question_id="question.id"
+ t-att-data-row_id="choice_data['row'].id"
+ t-att-data-answer_id="column_data['suggested_answer'].id" role="img" aria-label="Survey filter" title="Survey filter"></i>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ <div t-if="comment_lines" t-call="survey.question_result_comments" />
+ </div>
+ </template>
+
+ <template id="question_result_comments" name="Question: comments">
+ <table class="table table-hover table-sm" t-att-id="'survey_table_question_%d' % question.id">
+ <thead>
+ <tr>
+ <th>#</th>
+ <th>Comment</th>
+ </tr>
+ </thead>
+ <tbody>
+ <tr t-foreach="comment_lines" t-as="input_line">
+ <td>
+ <t t-if="no_print_url"><t t-esc="input_line_index + 1"></t></t>
+ <t t-else="">
+ <a t-att-href="input_line.user_input_id.get_print_url()">
+ <t t-esc="input_line_index + 1"></t>
+ </a>
+ </t>
+ </td>
+ <td>
+ <span t-field="input_line.value_char_box"></span><br/>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </template>
+
+ <template id="question_table_pagination" name="Survey: statistics table pagination">
+ <ul t-att-id="'pagination_%d' % question.id" class="pagination" t-att-data-question_id="question.id" t-att-data-record_limit="page_record_limit">
+ <t t-if="len(table_data) > page_record_limit">
+ <t t-set="total" t-value="ceil(len(table_data) / page_record_limit) + 1"/>
+ <li t-foreach="range(1, total)" t-as="num"
+ t-att-class="'page-item o_survey_js_results_pagination %s' % ('active' if num == 1 else '')">
+ <a href="#" class="page-link" t-esc="num"></a>
+ </li>
+ </t>
+ </ul>
+ </template>
+</data>
+</odoo>
diff --git a/addons/survey/views/survey_templates_user_input_session.xml b/addons/survey/views/survey_templates_user_input_session.xml
new file mode 100644
index 00000000..68156c0c
--- /dev/null
+++ b/addons/survey/views/survey_templates_user_input_session.xml
@@ -0,0 +1,196 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+ <template id="user_input_session" name="Survey User Input Session" inherit_id="web.frontend_layout" primary="True">
+ <xpath expr="//div[@id='wrapwrap']" position="before">
+ <!--TODO DBE Fix me : If one day, there is a survey_livechat bridge module, put this in that module-->
+ <t t-set="no_livechat" t-value="True"/>
+ </xpath>
+ <xpath expr="//div[@id='wrapwrap']" position="attributes">
+ <attribute name="t-att-style" add="('height: 100%; overflow: auto; background: url(' + '/web/image/survey.survey/%s/background_image' % survey.id + ') no-repeat fixed center; box-shadow: inset 0 0 0 10000px rgba(255,255,255,.7); background-size: cover;') if survey and survey.background_image else 'height: 100%; overflow: auto;'"/>
+ </xpath>
+ <xpath expr="//head/t[@t-call-assets][last()]" position="after">
+ <t t-call-assets="survey.survey_assets" lazy_load="True"/>
+ <t t-call-assets="survey.survey_user_input_session_assets" lazy_load="True"/>
+ </xpath>
+ <xpath expr="//header" position="before">
+ <t t-set="no_header" t-value="True"/>
+ <t t-set="no_footer" t-value="True"/>
+ </xpath>
+ <xpath expr="//header" position="after">
+ <div id="wrap" class="oe_structure oe_empty"/>
+ </xpath>
+ </template>
+
+ <template id="user_input_session_open" name="Survey: Open Session">
+ <t t-call="survey.user_input_session">
+ <div class="wrap py-3 min-vh-100 align-items-center justify-content-center d-flex o_survey_session_open o_survey_session_manage"
+ t-att-data-survey-access-token="survey.access_token"
+ t-att-data-survey-id="survey.id"
+ t-att-data-is-start-screen="True">
+ <div class="w-75 p-4">
+ <div class="text-center">
+ <h1 class="mb-4" t-field="survey.title" />
+ <h2 class="mb-5 font-weight-normal">
+ <span>Go to <a t-att-href="survey.session_link" t-esc="survey.session_link" target="_blank" /></span>
+ <i class="fa fa-copy font-weight-normal ml-3 o_survey_session_copy" />
+ <input class="o_survey_session_copy_url d-none" type="text" t-att-value="survey.session_link" />
+ </h2>
+ <h2 class="font-weight-normal"><span>Waiting for attendees...</span>
+ <span class="ml-1 font-weight-bold o_survey_session_attendees_count" t-esc="survey.session_answer_count" />
+ </h2>
+ </div>
+ <a role="button"
+ class="font-weight-bold fa fa-chevron-right o_survey_session_navigation o_survey_session_navigation_next p-3" />
+ </div>
+ </div>
+ </t>
+ </template>
+
+ <template id="user_input_session_manage" name="Survey: Manage Session">
+ <t t-call="survey.user_input_session">
+ <t t-call="survey.user_input_session_manage_content" />
+ </t>
+ </template>
+
+ <template id="user_input_session_manage_content" name="Survey User Input Session Manage">
+ <t t-set="question" t-value="survey.session_question_id" />
+ <t t-set="is_scored_question" t-value="any(answer.answer_score for answer in question.suggested_answer_ids)" />
+ <t t-set="show_bar_chart" t-value="question.question_type in ['simple_choice', 'multiple_choice']" />
+ <t t-set="show_text_answers" t-value="question.question_type in ['char_box', 'date', 'datetime'] and not question.save_as_email and not question.save_as_nickname" />
+ <div class="wrap min-vh-100 align-items-center justify-content-center d-flex flex-column o_survey_session_manage"
+ t-att-style="'display: none;' if is_rpc_call else ''"
+ t-att-data-is-rpc-call="is_rpc_call"
+ t-att-data-survey-id="survey.id"
+ t-att-data-attendees-count="survey.session_answer_count"
+ t-att-data-survey-access-token="survey.access_token"
+ t-att-data-timer="survey.session_question_start_time.isoformat()"
+ t-att-data-time-limit-minutes="question.time_limit / 60"
+ t-att-data-is-scored-question="is_scored_question"
+ t-att-data-session-show-leaderboard="survey.session_show_leaderboard"
+ t-att-data-question-statistics="question_statistics_graph"
+ t-att-data-question-type="question.question_type"
+ t-att-data-has-correct-answers="any(answer.is_correct for answer in question.suggested_answer_ids)"
+ t-att-data-answers-validity="answers_validity"
+ t-att-data-is-last-question="is_last_question"
+ t-att-data-current-screen="'question' if is_scored_question else 'userInputs'"
+ t-att-data-show-bar-chart="show_bar_chart"
+ t-att-data-show-text-answers="show_text_answers">
+ <div class="o_survey_question_header flex-wrap px-3 w-100 d-flex justify-content-between align-items-center position-absolute">
+ <h3>
+ <span>Go to <a t-att-href="survey.session_link" t-esc="survey.session_link" target="_blank" /></span>
+ <i class="fa fa-copy font-weight-normal ml-3 mr-1 o_survey_session_copy" />
+ <input class="o_survey_session_copy_url d-none" type="text" t-att-value="survey.session_link" />
+ </h3>
+ <h1 t-if="question.is_time_limited" class="o_survey_timer_container">
+ <span class="o_survey_timer d-inline-block"/>
+ </h1>
+ <div class="text-right d-flex flex-column justify-content-center">
+ <div t-if="show_bar_chart or show_text_answers">
+ <div class="progress" title="Attendees are answering the question...">
+ <div class="progress-bar o_survey_session_progress_small font-weight-bold"
+ role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
+ <span class="px-2">0 / <t t-esc="survey.session_answer_count" /></span>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="container px-4 pb-3 pt96 d-flex flex-column o_survey_session_manage_container">
+ <a role="button"
+ class="font-weight-bold fa fa-chevron-right o_survey_session_navigation o_survey_session_navigation_next p-3" />
+ <a role="button"
+ class="font-weight-bold fa fa-chevron-left o_survey_session_navigation o_survey_session_navigation_previous p-3 d-none" />
+ <div class="o_survey_session_results flex-column flex-grow-1">
+ <div class="row">
+ <div class="col-lg-12"><h1 t-esc="question.title"></h1></div>
+ </div>
+ <div t-attf-class="d-flex flex-column flex-grow-1 #{'justify-content-center' if not show_text_answers else ''} #{'align-items-center' if show_bar_chart else ''}">
+ <!-- Has to stay in 'style' attribute for Chartjs -->
+ <div t-if="show_bar_chart" class="p-2 o_survey_session_chart"
+ style="position: relative; width: 75vw; height: 70vh;">
+ <!-- canvas element for drawing bar chart -->
+ <canvas />
+ </div>
+ <div t-elif="show_text_answers" class="p-2 pt-4 o_survey_session_text_answers_container">
+ </div>
+ <div t-elif="question.is_page and not is_html_empty(question.description)" class="mb-6 o_survey_manage_fontsize_14" t-field="question.description" />
+ <div t-else="" class="mb-6">
+ <h2 class="font-weight-normal mb-3">
+ <span>Waiting for attendees...</span>
+ <span>
+ <span class="o_survey_session_answer_count">0</span>
+ /
+ <span t-esc="survey.session_answer_count" />
+ </span>
+ </h2>
+ <div class="progress">
+ <div class="progress-bar font-weight-bold" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100"></div>
+ </div>
+ <fieldset disabled="disabled" class="mt-5" t-if="question.question_type == 'matrix'" t-call="survey.question_container">
+ <t t-set="hide_question_title" t-value="true" />
+ <t t-set="answer" t-value="env['survey.user_input']" />
+ <t t-set="survey_form_readonly" t-value="True"/>
+ </fieldset>
+ </div>
+ </div>
+ </div>
+ <div class="o_survey_session_leaderboard w-100 flex-column flex-grow-1" style="display: none;">
+ <div class="d-flex">
+ <h1 class="o_survey_session_leaderboard_title flex-grow-1">
+ <span t-if="is_last_question">Final Leaderboard</span>
+ <span t-else="">Leaderboard</span>
+ </h1>
+ <div t-att-class="'o_survey_leaderboard_buttons font-weight-bold %s' % 'd-none' if not is_last_question else ''">
+ <a href="#" role="button" class="o_survey_session_close btn btn-primary mr-4"><i class="fa fa-close"/> Close</a>
+ <a href="#" role="button" class="o_survey_session_close btn btn-primary" t-att-data-show-results="True"><i class="fa fa-bar-chart"/> Results</a>
+ </div>
+ </div>
+ <div class="justify-content-center d-flex flex-column flex-grow-1 mt-5 mb-5 pb-5 o_survey_session_leaderboard_container"/>
+ </div>
+ </div>
+ </div>
+ </template>
+
+ <template id="user_input_session_leaderboard" name="Survey User Input Leaderboard">
+ <div t-if="leaderboard" class="position-relative mb-5" t-attf-style="height: calc(3.8rem * #{len(leaderboard)});">
+ <t t-set="max_score" t-value="max(score.get('scoring_total', 1) for score in leaderboard) or 1" />
+ <t t-set="max_updated_score" t-value="max(score.get('updated_score', 1) for score in leaderboard)" />
+ <t t-foreach="leaderboard" t-as="score">
+ <div class="o_survey_session_leaderboard_item ml-2 d-flex position-absolute"
+ t-attf-style="top: calc(#{score_index} * 3.8rem);"
+ t-att-data-current-position="str(score_index)"
+ t-att-data-new-position="str(score.get('leaderboard_position', score_index))"
+ t-att-data-question-score="str(round(score.get('question_score', 0)))"
+ t-att-data-current-score="str(round(score.get('scoring_total', 0)))"
+ t-att-data-updated-score="str(round(score.get('updated_score', 0)))"
+ t-att-data-max-question-score="round(score.get('max_question_score', 1))"
+ t-att-data-max-updated-score="round(max_updated_score)">
+ <div class="d-inline-block font-weight-bold align-top">
+ <div class="d-inline-block mr-2 o_survey_session_leaderboard_score" t-esc="'%.0f p' % score['scoring_total']" />
+ </div>
+ <!-- We keep "18rem" of space to display the points / nickname.
+ Then, the length of the bar is a percentage of the attendee's score compared to the max_score. -->
+ <t t-set="width_ratio" t-value="round(round(score['scoring_total']) / round(max_score), 3)"/>
+ <t t-set="width_ratio_question" t-value="str(round(round(score.get('question_score', 0)) / round(score.get('max_question_score', 1)), 3))"/>
+ <div class="o_survey_session_leaderboard_bar ml-2 align-top d-inline-block text-right font-weight-bold"
+ t-att-style="'width: calc(calc(%s - 18rem) * %s)' % ('100%', width_ratio)"
+ t-att-data-width-ratio="width_ratio">
+ </div>
+ <div class="o_survey_session_leaderboard_bar_question mr-2 align-top d-inline-block text-right font-weight-bold position-relative"
+ style="width: 0px;"
+ t-att-data-width-ratio="width_ratio_question"
+ t-att-data-max-question-score="str(score.get('max_question_score', 1))"
+ t-att-data-question-score="str(score.get('question_score', 0))">
+ <div class="o_survey_session_leaderboard_bar_question_score position-absolute"></div>
+ </div>
+ <div class="o_survey_session_leaderboard_name d-inline-block">
+ <span t-if="score.get('nickname')" t-esc="score['nickname']" />
+ <span t-else="">Anonymous</span>
+ </div>
+ </div>
+ </t>
+ </div>
+ </template>
+</data>
+</odoo>
diff --git a/addons/survey/views/survey_user_views.xml b/addons/survey/views/survey_user_views.xml
new file mode 100644
index 00000000..bda3624d
--- /dev/null
+++ b/addons/survey/views/survey_user_views.xml
@@ -0,0 +1,232 @@
+<?xml version="1.0" encoding="utf-8"?>
+<odoo>
+<data>
+ <!-- USER INPUTS -->
+ <record id="survey_user_input_view_search" model="ir.ui.view">
+ <field name="name">survey.user_input.view.search</field>
+ <field name="model">survey.user_input</field>
+ <field name="arch" type="xml">
+ <search string="Search Survey">
+ <field name="survey_id"/>
+ <field name="email"/>
+ <field name="partner_id"/>
+ <filter name="completed" string="Completed" domain="[('state', '=', 'done')]"/>
+ <filter string="In Progress" name="in_progress" domain="[('state', '=', 'in_progress')]"/>
+ <filter string="New" name="new" domain="[('state', '=', 'new')]"/>
+ <separator/>
+ <filter string="Quizz passed" name="scoring_success" domain="[('scoring_success','=', True)]"/>
+ <separator/>
+ <filter string="Test Entries" name="test" domain="[('test_entry','=', True)]"/>
+ <filter string="Except Test Entries" name="not_test" domain="[('test_entry','=', False)]" invisible="1"/>
+ <group expand="0" string="Group By">
+ <filter name="group_by_survey" string="Survey" domain="[]" context="{'group_by': 'survey_id'}"/>
+ <filter string="Email" name="group_by_email" domain="[]" context="{'group_by': 'email'}"/>
+ <filter string="Partner" name="group_by_partner" domain="[]" context="{'group_by': 'partner_id'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record id="survey_user_input_view_form" model="ir.ui.view">
+ <field name="name">survey.user_input.view.form</field>
+ <field name="model">survey.user_input</field>
+ <field name="arch" type="xml">
+ <form string="Survey User inputs" create="false">
+ <header>
+ <button name="action_resend" string="Resend Invitation" type="object" class="oe_highlight"
+ attrs="{'invisible': ['|', ('state', '=', 'done'), '&amp;', ('partner_id', '=', False), ('email', '=', False)]}"/>
+ <button name="action_print_answers" states="done" string="Print" type="object" class="oe_highlight"/>
+ <field name="state" widget="statusbar"/>
+ </header>
+ <sheet>
+ <div class="oe_button_box" name="button_box"/>
+ <group col="2">
+ <group>
+ <field name="survey_id"/>
+ <field name="create_date"/>
+ <field name="is_attempts_limited" invisible="1"/>
+ <label for="attempts_number" string="Attempt n°" attrs="{'invisible': ['|', ('is_attempts_limited', '=', False), '|', ('test_entry', '=', True), ('state', '!=', 'done')]}"/>
+ <div attrs="{'invisible': ['|', ('is_attempts_limited', '=', False), '|', ('test_entry', '=', True), ('state', '!=', 'done')]}">
+ <field name="attempts_number" nolabel="1"/>
+ /
+ <field name="attempts_limit" nolabel="1" />
+ </div>
+ <field name="access_token" groups="base.group_no_one"/>
+ </group>
+ <group>
+ <field name="deadline"/>
+ <field name="partner_id"/>
+ <field name="email" widget="email"/>
+ <field name="test_entry" groups="base.group_no_one"/>
+ <field name="scoring_type" invisible="1"/>
+ <field name="scoring_percentage" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}"/>
+ <field name="scoring_success" attrs="{'invisible': [('scoring_type', '=', 'no_scoring')]}"/>
+ </group>
+ </group>
+ <field name="user_input_line_ids" mode="tree" attrs="{'readonly': False}">
+ <tree>
+ <field name="question_sequence" invisible="1"/>
+ <field name="question_id"/>
+ <field name="page_id"/>
+ <field name="answer_type"/>
+ <field name="skipped"/>
+ <field name="create_date"/>
+ <field name="answer_is_correct"/>
+ <field name="answer_score"/>
+ </tree>
+ </field>
+ </sheet>
+ </form>
+ </field>
+ </record>
+
+ <record id="survey_user_input_view_tree" model="ir.ui.view">
+ <field name="name">survey.user_input.view.tree</field>
+ <field name="model">survey.user_input</field>
+ <field name="arch" type="xml">
+ <tree string="Survey User inputs" decoration-muted="test_entry == True" create="false">
+ <field name="survey_id"/>
+ <field name="create_date"/>
+ <field name="deadline"/>
+ <field name="partner_id"/>
+ <field name="email"/>
+ <field name="attempts_number"/>
+ <field name="state"/>
+ <field name="test_entry" invisible="True"/>
+ <field name="scoring_success"/>
+ <field name="scoring_percentage"/>
+ </tree>
+ </field>
+ </record>
+
+ <record id="survey_user_input_viuew_kanban" model="ir.ui.view">
+ <field name="name">survey.user_input.view.kanban</field>
+ <field name="model">survey.user_input</field>
+ <field name="arch" type="xml">
+ <kanban create="false">
+ <field name="survey_id"/>
+ <field name="create_date"/>
+ <field name="partner_id"/>
+ <field name="email"/>
+ <field name="state"/>
+ <templates>
+ <t t-name="kanban-box">
+ <div t-attf-class="oe_kanban_global_click">
+ <div class="o_kanban_record_top">
+ <div class="o_kanban_record_headings">
+ <strong class="o_kanban_record_title"><t t-esc="record.survey_id.value"/></strong>
+ </div>
+ </div>
+ <div class="o_kanban_record_bottom">
+ <div class="oe_kanban_bottom_left">
+ <field name="create_date"/>
+ </div>
+ <div class="oe_kanban_bottom_right mr4">
+ <field name="state" widget="label_selection" options="{'classes': {'new': 'default', 'done': 'success', 'in_progress':'warning'}}"/>
+ </div>
+ </div>
+ </div>
+ </t>
+ </templates>
+ </kanban>
+ </field>
+ </record>
+
+ <record model="ir.actions.act_window" id="action_survey_user_input">
+ <field name="name">Participations</field>
+ <field name="res_model">survey.user_input</field>
+ <field name="view_mode">tree,kanban,form</field>
+ <field name="view_id" ref="survey_user_input_view_tree"></field>
+ <field name="search_view_id" ref="survey_user_input_view_search"/>
+ <field name="context">{'search_default_group_by_survey': True}</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ Nobody has replied to your surveys yet
+ </p>
+ </field>
+ </record>
+
+ <!-- USER INPUT LINES
+ .. note:: these views are useful mainly for technical users/administrators -->
+ <record id="survey_user_input_line_view_form" model="ir.ui.view">
+ <field name="name">survey.user_input.line.view.form</field>
+ <field name="model">survey.user_input.line</field>
+ <field name="arch" type="xml">
+ <form string="User input line details" create="false">
+ <sheet>
+ <group col="4">
+ <field name="question_id"/>
+ <field name="create_date"/>
+ <field name="answer_type"/>
+ <field name="skipped" />
+ <field name="answer_score" groups="base.group_no_one"/>
+ </group>
+ <group>
+ <field name="value_char_box" colspan='2' attrs="{'invisible': [('answer_type','!=','char_box')]}"/>
+ <field name="value_numerical_box" colspan='2' attrs="{'invisible': [('answer_type','!=','numerical_box')]}"/>
+ <field name="value_date" colspan='2' attrs="{'invisible': [('answer_type','!=','date')]}"/>
+ <field name="value_datetime" colspan='2' attrs="{'invisible': [('answer_type','!=','datetime')]}"/>
+ <field name="value_text_box" colspan='2' attrs="{'invisible': [('answer_type','!=','text_box')]}"/>
+ <field name="matrix_row_id" colspan='2' />
+ <field name="suggested_answer_id" colspan='2' attrs="{'invisible': [('answer_type','!=','suggestion')]}"/>
+ </group>
+ </sheet>
+ </form>
+ </field>
+ </record>
+ <record id="survey_response_line_view_tree" model="ir.ui.view">
+ <field name="name">survey.user_input.line.view.tree</field>
+ <field name="model">survey.user_input.line</field>
+ <field name="arch" type="xml">
+ <tree string="Survey Answer Line" create="false">
+ <field name="survey_id"/>
+ <field name="user_input_id"/>
+ <field name="question_id"/>
+ <field name="create_date"/>
+ <field name="answer_type"/>
+ <field name="skipped"/>
+ <field name="answer_score" groups="base.group_no_one"/>
+ </tree>
+ </field>
+ </record>
+ <record id="survey_user_input_line_view_search" model="ir.ui.view">
+ <field name="name">survey.user_input.line.view.search</field>
+ <field name="model">survey.user_input.line</field>
+ <field name="arch" type="xml">
+ <search string="Search User input lines">
+ <field name="user_input_id"/>
+ <field name="survey_id"/>
+ <group expand="1" string="Group By">
+ <filter name="group_by_survey" string="Survey" domain="[]" context="{'group_by':'survey_id'}"/>
+ <filter name="group_by_user_input" string="User Input" domain="[]" context="{'group_by':'user_input_id'}"/>
+ </group>
+ </search>
+ </field>
+ </record>
+
+ <record id="survey_user_input_line_action" model="ir.actions.act_window">
+ <field name="name">Detailed Answers</field>
+ <field name="res_model">survey.user_input.line</field>
+ <field name="view_mode">tree,form</field>
+ <field name="search_view_id" ref="survey_user_input_line_view_search"/>
+ <field name="context">{'search_default_group_by_survey': True, 'search_default_group_by_user_input': True}</field>
+ <field name="help" type="html">
+ <p class="o_view_nocontent_empty_folder">
+ No user input lines found
+ </p>
+ </field>
+ </record>
+
+ <menuitem name="Participations"
+ id="menu_survey_type_form1"
+ action="action_survey_user_input"
+ parent="survey_menu_user_inputs"
+ sequence="1"/>
+ <menuitem name="Detailed Answers"
+ id="menu_survey_response_line_form"
+ action="survey_user_input_line_action"
+ parent="survey_menu_user_inputs"
+ sequence="4"
+ groups="base.group_no_one"/>
+</data>
+</odoo>