RATIONALE Events are sometimes held online, gathering a community. In this merge we improve Event application to better support full-online events with improved tracks, wishlists, chat rooms, ... PURPOSE Allow to configure a quiz on event tracks, much like eLearning. The quiz is taken at the end of the live stream / track video. (Or when the talk is 'live' of 'done'). SPECIFICATIONS Users can now configure an event.quiz on event.track. The quiz is a simple collection of event.quiz.questions that in turn contain a few event.quiz.answers. Only one of the answer is considered as correct and should be configured with "awarded_points" greater than 0. On the event.track frontend page, attendees can take the quiz when the track is "live" (or "done") and earn the total amount of configured awarded_points. Each quiz can only be taken once (if you fail, you can't try again). Attendees are then ranked in a leaderboard that is displayed in the "Community" section of the event frontend menus. The leaderboard allows to see your own position as well as basic search for other attendees. The points earned during the event are event-specific and will not be shared with other instances of event.event. Points as well as quiz completion are stored in the relationship between a visitor and a track (event.track.visitor). The models are very much based on a similar feature in website_slides, even though the implementation in event is not karma based. We will probably have to merge the features later into a base gamification_quiz module. LINKS Task ID-2252655 (Main Online Event task) Task ID-2283771 (Quizzes on Talks, Leaderboard) Co-Authored-By: Aurélien Warnon <awa@odoo.com> Co-Authored-By: David Beguin <dbe@odoo.com> Co-Authored-By: Quentin Mourier <qmo@odoo.com> Co-Authored-By: Thibault Delavallée <tde@odoo.com>
67 lines
3.1 KiB
Python
67 lines
3.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo import api, fields, models
|
|
from odoo.osv import expression
|
|
|
|
|
|
class EventTrack(models.Model):
|
|
_inherit = ['event.track']
|
|
|
|
quiz_id = fields.Many2one('event.quiz', string="Quiz", groups="event.group_event_user")
|
|
quiz_questions_count = fields.Integer(string="# Quiz Questions", compute='_compute_quiz_questions_count', groups="event.group_event_user")
|
|
is_quiz_completed = fields.Boolean('Is Quiz Done', compute='_compute_quiz_data')
|
|
quiz_points = fields.Integer('Quiz Points', compute='_compute_quiz_data')
|
|
|
|
@api.depends('quiz_id.question_ids')
|
|
def _compute_quiz_questions_count(self):
|
|
for track in self:
|
|
track.quiz_questions_count = len(track.quiz_id.question_ids)
|
|
|
|
@api.depends('quiz_id', 'event_track_visitor_ids.visitor_id',
|
|
'event_track_visitor_ids.partner_id', 'event_track_visitor_ids.quiz_completed',
|
|
'event_track_visitor_ids.quiz_points')
|
|
@api.depends_context('uid')
|
|
def _compute_quiz_data(self):
|
|
tracks_quiz = self.filtered(lambda track: track.quiz_id)
|
|
(self - tracks_quiz).is_quiz_completed = False
|
|
(self - tracks_quiz).quiz_points = 0
|
|
if tracks_quiz:
|
|
current_visitor = self.env['website.visitor']._get_visitor_from_request(force_create=False)
|
|
if self.env.user._is_public() and not current_visitor:
|
|
for track in tracks_quiz:
|
|
track.is_quiz_completed = False
|
|
track.quiz_points = 0
|
|
else:
|
|
if self.env.user._is_public():
|
|
domain = [('visitor_id', '=', current_visitor.id)]
|
|
elif current_visitor:
|
|
domain = [
|
|
'|',
|
|
('partner_id', '=', self.env.user.partner_id.id),
|
|
('visitor_id', '=', current_visitor.id)
|
|
]
|
|
else:
|
|
domain = [('partner_id', '=', self.env.user.partner_id.id)]
|
|
|
|
event_track_visitors = self.env['event.track.visitor'].sudo().search_read(
|
|
expression.AND([
|
|
domain,
|
|
[('track_id', 'in', tracks_quiz.ids)]
|
|
]), fields=['track_id', 'quiz_completed', 'quiz_points']
|
|
)
|
|
|
|
quiz_visitor_map = {
|
|
track_visitor['track_id'][0]: {
|
|
'quiz_completed': track_visitor['quiz_completed'],
|
|
'quiz_points': track_visitor['quiz_points']
|
|
} for track_visitor in event_track_visitors
|
|
}
|
|
for track in tracks_quiz:
|
|
if quiz_visitor_map.get(track.id):
|
|
track.is_quiz_completed = quiz_visitor_map[track.id]['quiz_completed']
|
|
track.quiz_points = quiz_visitor_map[track.id]['quiz_points']
|
|
else:
|
|
track.is_quiz_completed = False
|
|
track.quiz_points = 0
|