[REF] website_slide_survey: improve integration into eLeaning application

PURPOSE

eLearning should have its own application in manager. Indeed this is becoming
a big application and having it embedded inside Website application is not
enough anymore. It should also hold updated and easy-to-use menus,
navigation, actions and views in backend.

SPECIFICATIONS

Add menu entry inside Courses
  * Certifications: kanban view of surveys of type certificate

Add menu entry inside Reporting
  * Certifications: list view on surveys of type certificate
    Columns: Title, Survey Stage, Registered People, Certified People, Attempts
    Success Rate (certified/attempts), Average Results

LINKS

Task 1978729
PR #35061

Co-Authored-By: Thibault Delavallée <tde@odoo.com>
Co-Authored-By: Jérémy Hennecart <jeh@odoo.com>
This commit is contained in:
Jérémy Hennecart
2019-08-05 08:43:21 +00:00
committed by Thibault Delavallée
co-authored by Thibault Delavallée
parent ee10b19f67
commit ee29641b08
8 changed files with 86 additions and 34 deletions
+18 -27
View File
@@ -71,11 +71,11 @@ class Survey(models.Model):
users_can_signup = fields.Boolean('Users can signup', compute='_compute_users_can_signup')
public_url = fields.Char("Public link", compute="_compute_survey_url")
# statistics
invite_count = fields.Integer("Invite", compute="_compute_survey_statistic")
answer_count = fields.Integer("Started", compute="_compute_survey_statistic")
answer_done_count = fields.Integer("Completed", compute="_compute_survey_statistic")
certified_count = fields.Integer("Certified", compute="_compute_certified_count")
answer_count = fields.Integer("Registered", compute="_compute_survey_statistic")
answer_done_count = fields.Integer("Attempts", compute="_compute_survey_statistic")
answer_score_avg = fields.Float("Avg Score %", compute="_compute_survey_statistic")
certified_count = fields.Integer("Certified", compute="_compute_survey_statistic")
certified_ratio = fields.Integer("Certified Ratio", compute="_compute_certified_ratio")
# scoring and certification fields
scoring_type = fields.Selection([
('no_scoring', 'No scoring'),
@@ -121,38 +121,30 @@ class Survey(models.Model):
for survey in self:
survey.users_can_signup = signup_allowed
@api.depends('user_input_ids.state', 'user_input_ids.test_entry')
@api.depends('user_input_ids.input_type', 'user_input_ids.state', 'user_input_ids.test_entry', 'user_input_ids.quizz_score', 'user_input_ids.quizz_passed')
def _compute_survey_statistic(self):
stat = dict((cid, dict(invite_count=0, answer_count=0, answer_done_count=0)) for cid in self.ids)
stat = dict((cid, dict(answer_count=0, answer_done_count=0, certified_count=0, answer_score_avg_total=0.0)) for cid in self.ids)
UserInput = self.env['survey.user_input']
base_domain = ['&', ('survey_id', 'in', self.ids), ('test_entry', '!=', True)]
read_group_res = UserInput.read_group(base_domain, ['input_type', 'state'], ['survey_id', 'input_type', 'state'], lazy=False)
read_group_res = UserInput.read_group(base_domain, ['survey_id', 'state'], ['survey_id', 'input_type', 'state', 'quizz_score', 'quizz_passed'], lazy=False)
for item in read_group_res:
stat[item['survey_id'][0]]['answer_count'] += item['__count']
stat[item['survey_id'][0]]['answer_score_avg_total'] += item['quizz_score']
if item['state'] == 'done':
stat[item['survey_id'][0]]['answer_done_count'] += item['__count']
if item['input_type'] == 'link':
stat[item['survey_id'][0]]['invite_count'] += item['__count']
if item['quizz_passed']:
stat[item['survey_id'][0]]['certified_count'] += item['__count']
for survey in self:
avg_total = stat[survey.id].pop('answer_score_avg_total')
stat[survey.id]['answer_score_avg'] = avg_total / (stat[survey.id]['answer_done_count'] or 1)
survey.update(stat[survey.id])
@api.depends('certificate', 'user_input_ids.quizz_passed', 'user_input_ids.test_entry')
def _compute_certified_count(self):
stat = dict((cid, 0) for cid in self.ids)
certificate_surveys = self.filtered(lambda survey: survey.certificate)
if certificate_surveys:
read_group_res = self.env['survey.user_input'].read_group(
[('survey_id', 'in', certificate_surveys.ids), ('test_entry', '!=', True), ('quizz_passed', '=', True)],
[],
['survey_id']
)
for item in read_group_res:
stat[item['survey_id'][0]] += item['survey_id_count']
@api.depends('certified_count', 'answer_done_count')
def _compute_certified_ratio(self):
for survey in self:
survey.certified_count = stat.get(survey.id, 0)
survey.certified_ratio = survey.certified_count / (survey.answer_done_count or 1.0)
def _compute_survey_url(self):
""" Computes a public URL for the survey """
@@ -614,12 +606,11 @@ class Survey(models.Model):
action['context'] = ctx
return action
def action_survey_user_input_invite(self):
def action_survey_user_input(self):
action_rec = self.env.ref('survey.action_survey_user_input_notest')
action = action_rec.read()[0]
ctx = dict(self.env.context)
ctx.update({'search_default_survey_id': self.ids[0],
'search_default_invite': 1})
ctx.update({'search_default_survey_id': self.ids[0]})
action['context'] = ctx
return action
+1 -2
View File
@@ -61,9 +61,8 @@ class SurveyUserInput(models.Model):
# Pre-defined questions
question_ids = fields.Many2many('survey.question', string='Predefined Questions', readonly=True)
deadline = fields.Datetime('Deadline', help="Datetime until customer can open the survey and submit answers")
quizz_score = fields.Float("Score (%)", compute="_compute_quizz_score")
# Stored for performance reasons while displaying results page
quizz_score = fields.Float("Score (%)", compute="_compute_quizz_score", store=True, compute_sudo=True)
quizz_passed = fields.Boolean('Quizz Passed', compute='_compute_quizz_passed', store=True, compute_sudo=True)
@api.depends('user_input_line_ids.answer_score', 'user_input_line_ids.question_id')
+8 -4
View File
@@ -21,12 +21,12 @@
<sheet>
<widget name="web_ribbon" text="Archived" bg_color="bg-danger" attrs="{'invisible': [('active', '=', True)]}"/>
<div class="oe_button_box" name="button_box">
<button name="action_survey_user_input_invite"
<button name="action_survey_user_input"
type="object"
class="oe_stat_button"
attrs="{'invisible': [('access_mode', '=', 'public')]}"
icon="fa-envelope-o">
<field string="Invitations" name="invite_count" widget="statinfo"/>
<field string="Registered" name="answer_count" widget="statinfo"/>
</button>
<button name="action_survey_user_input_certified"
type="object"
@@ -132,9 +132,11 @@
<field name="certificate" invisible="1"/>
<field name="title"/>
<field name="state"/>
<field name="invite_count"/>
<field name="answer_count"/>
<field name="answer_done_count"/>
<field name="certified_count"/>
<field name="certified_ratio"/>
<field name="answer_score_avg"/>
<button name="certificate" icon="fa-trophy" title="Certificate" aria-label="Certificate" attrs="{'invisible': [('certificate', '=', False)]}"/>
<!-- Tweak as icons aren't directly supported in xml -->
</tree>
@@ -144,7 +146,7 @@
<field name="name">Kanban view for survey</field>
<field name="model">survey.survey</field>
<field name="arch" type="xml">
<kanban default_group_by="state">
<kanban>
<field name="state" />
<field name="title" />
<field name="answer_done_count" />
@@ -221,6 +223,7 @@
]"/>
<group expand="0" string="Group By">
<filter string="Category" name="groupby_category" context="{'group_by': 'category'}"/>
<filter string="State" name="groupby_state" context="{'group_by': 'state'}"/>
</group>
</search>
</field>
@@ -230,6 +233,7 @@
<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
@@ -13,6 +13,8 @@
'views/assets.xml',
'views/slide_channel_views.xml',
'views/slide_slide_views.xml',
'views/survey_survey_views.xml',
'views/website_slides_menu_views.xml',
'views/website_slides_templates_course.xml',
'views/website_slides_templates_lesson.xml',
'views/website_slides_templates_lesson_fullscreen.xml',
@@ -16,7 +16,7 @@
<field name="model">slide.channel</field>
<field name="inherit_id" ref="website_slides.slide_channel_view_kanban"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='members_running_count']" position="after">
<xpath expr="//field[@name='website_published']" position="after">
<field name="nbr_certification"/>
</xpath>
<xpath expr="//a[@name='action_redirect_to_done_members']/span" position="replace">
@@ -12,4 +12,18 @@
</xpath>
</field>
</record>
<record id="slide_slide_action_certification" model="ir.actions.act_window">
<field name="name">Certifications</field>
<field name="res_model">slide.slide</field>
<field name="view_mode">tree,form,graph</field>
<field name="domain">[('slide_type', '=', 'certification')]</field>
<field name="context">{'default_slide_type': 'certification'}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Add a new certification
</p>
</field>
<field name="view_id" ref="website_slides.view_slide_slide_tree"/>
</record>
</odoo>
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="survey_survey_action_slides" model="ir.actions.act_window">
<field name="name">Certifications</field>
<field name="res_model">survey.survey</field>
<field name="view_mode">kanban,tree,form</field>
<field name="domain">[('certificate', '=', True)]</field>
<field name="context">{'default_certificate': True}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Add a new certification
</p>
</field>
</record>
<record id="survey_survey_action_slides_report" model="ir.actions.act_window">
<field name="name">Certifications</field>
<field name="res_model">survey.survey</field>
<field name="view_mode">tree,kanban,form,graph</field>
<field name="domain">[('certificate', '=', True)]</field>
<field name="context">{'default_certificate': True}</field>
<field name="help" type="html">
<p class="o_view_nocontent_smiling_face">
Add a new certification
</p>
</field>
</record>
</odoo>
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<menuitem name="Certifications"
id="website_slides_menu_courses_certification"
parent="website_slides.website_slides_menu_courses"
sequence="3"
action="survey_survey_action_slides"/>
<menuitem name="Certifications"
id="website_slides_menu_report_certification"
parent="website_slides.website_slides_menu_report"
sequence="40"
action="survey_survey_action_slides_report"/>
</odoo>