diff options
Diffstat (limited to 'addons/website_slides/models')
| -rw-r--r-- | addons/website_slides/models/__init__.py | 1 | ||||
| -rw-r--r-- | addons/website_slides/models/slide_channel.py | 9 | ||||
| -rw-r--r-- | addons/website_slides/models/slide_question.py | 51 | ||||
| -rw-r--r-- | addons/website_slides/models/slide_slide.py | 22 |
4 files changed, 77 insertions, 6 deletions
diff --git a/addons/website_slides/models/__init__.py b/addons/website_slides/models/__init__.py index 4b8210c6caa..0fcfe6373ab 100644 --- a/addons/website_slides/models/__init__.py +++ b/addons/website_slides/models/__init__.py @@ -2,6 +2,7 @@ from . import gamification_challenge from . import slide_slide +from . import slide_question from . import slide_channel from . import slide_channel_tag from . import slide_channel_invite diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index dd772a8ec7b..6bbd0e3b297 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -101,6 +101,7 @@ class Channel(models.Model): nbr_videos = fields.Integer('Number of Videos', compute='_compute_slides_statistics', store=True) nbr_infographics = fields.Integer('Number of Infographics', compute='_compute_slides_statistics', store=True) nbr_webpages = fields.Integer("Number of Webpages", compute='_compute_slides_statistics', store=True) + nbr_quizs = fields.Integer("Number of quizzes", compute="_compute_slides_statistics", store=True) total_slides = fields.Integer('# Slides', compute='_compute_slides_statistics', store=True, oldname='total') total_views = fields.Integer('# Views', compute='_compute_slides_statistics', store=True) total_votes = fields.Integer('# Votes', compute='_compute_slides_statistics', store=True) @@ -174,7 +175,7 @@ class Channel(models.Model): def _compute_slides_statistics(self): result = dict((cid, dict(total_slides=0, total_views=0, total_votes=0, total_time=0)) for cid in self.ids) read_group_res = self.env['slide.slide'].read_group( - [('is_published', '=', True), ('channel_id', 'in', self.ids)], + [('is_published', '=', True),('channel_id', 'in', self.ids)], ['channel_id', 'slide_type', 'likes', 'dislikes', 'total_views', 'completion_time'], groupby=['channel_id', 'slide_type'], lazy=False) @@ -195,7 +196,7 @@ class Channel(models.Model): def _compute_slides_statistics_type(self, read_group_res): """ Can be overridden to compute stats on added slide_types """ - result = dict((cid, dict(nbr_presentations=0, nbr_documents=0, nbr_videos=0, nbr_infographics=0, nbr_webpages=0)) for cid in self.ids) + result = dict((cid, dict(nbr_presentations=0, nbr_documents=0, nbr_videos=0, nbr_infographics=0, nbr_webpages=0, nbr_quizs=0)) for cid in self.ids) for res_group in read_group_res: cid = res_group['channel_id'][0] result[cid]['nbr_presentations'] += res_group.get('slide_type', '') == 'presentation' and res_group['__count'] or 0 @@ -203,6 +204,7 @@ class Channel(models.Model): result[cid]['nbr_videos'] += res_group.get('slide_type', '') == 'video' and res_group['__count'] or 0 result[cid]['nbr_infographics'] += res_group.get('slide_type', '') == 'infographic' and res_group['__count'] or 0 result[cid]['nbr_webpages'] += res_group.get('slide_type', '') == 'webpage' and res_group['__count'] or 0 + result[cid]['nbr_quizs'] += res_group.get('slide_type', '') == 'quiz' and res_group['__count'] or 0 return result @api.depends('slide_partner_ids') @@ -409,6 +411,7 @@ class Category(models.Model): nbr_videos = fields.Integer("Number of Videos", compute='_count_presentations', store=True) nbr_infographics = fields.Integer("Number of Infographics", compute='_count_presentations', store=True) nbr_webpages = fields.Integer("Number of Webpages", compute='_count_presentations', store=True) + nbr_quizs = fields.Integer("Number of quizzes", compute="_count_presentations", store=True) total_slides = fields.Integer(compute='_count_presentations', store=True, oldname='total') @api.depends('slide_ids.slide_type', 'slide_ids.is_published') @@ -432,6 +435,7 @@ class Category(models.Model): 'nbr_videos': result[record_id].get('video', 0), 'nbr_infographics': result[record_id].get('infographic', 0), 'nbr_webpages': result[record_id].get('webpage', 0), + 'nbr_quizs': result[record_id].get('quiz', 0), 'total_slides': 0 } @@ -440,5 +444,6 @@ class Category(models.Model): statistics['total_slides'] += statistics['nbr_videos'] statistics['total_slides'] += statistics['nbr_infographics'] statistics['total_slides'] += statistics['nbr_webpages'] + statistics['total_slides'] += statistics['nbr_quizs'] return statistics diff --git a/addons/website_slides/models/slide_question.py b/addons/website_slides/models/slide_question.py new file mode 100644 index 00000000000..0193558ba46 --- /dev/null +++ b/addons/website_slides/models/slide_question.py @@ -0,0 +1,51 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import api, fields, models, _ +from odoo.exceptions import ValidationError + + +class SlideQuestion(models.Model): + _name = "slide.question" + _rec_name = "question" + _description = """ + Question for a slide. A slide can have multiple questions and each question + must have at least 2 possible answers and only one good answer. + """ + + sequence = fields.Integer("Sequence", default=10) + question = fields.Char("Question Name", required=True) + slide_id = fields.Many2one('slide.slide', string="Slide") + answer_ids = fields.One2many('slide.answer', 'question_id', string="Answer") + + @api.constrains('answer_ids') + def _check_only_one_good_answer(self): + for question in self: + good_answer_count = 0 + for answer in question.answer_ids: + if answer.is_correct: + good_answer_count += 1 + if good_answer_count > 1: + raise ValidationError(_('A question can only have one good answer')) + + @api.constrains('answer_ids') + def _check_correct_answer(self): + for question in self: + if not any([answer.is_correct for answer in question.answer_ids]): + raise ValidationError(_("A question must at least have one good answer")) + + @api.constrains('answer_ids') + def _check_at_least_2_answers(self): + for question in self: + if len(question.answer_ids) < 2: + raise ValidationError(_("A question must at least have two possible answers")) + + +class SlideAnswer(models.Model): + _name = "slide.answer" + _rec_name = "text_value" + _description = """Answer for a slide question""" + + question_id = fields.Many2one('slide.question', string="Question") + text_value = fields.Char("Answer", required=True,) + is_correct = fields.Boolean("Is correct answer", default=False) diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index 35b9fefc4e5..a71446b82fa 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -23,12 +23,14 @@ class SlidePartnerRelation(models.Model): _description = 'Slide / Partner decorated m2m' _table = 'slide_slide_partner' - slide_id = fields.Many2one('slide.slide', index=True, required=True) + slide_id = fields.Many2one('slide.slide', ondelete="cascade", index=True, required=True) channel_id = fields.Many2one('slide.channel', string="Channel", related="slide_id.channel_id", store=True, index=True) partner_id = fields.Many2one('res.partner', index=True, required=True) vote = fields.Integer('Vote', default=0) completed = fields.Boolean('Completed') + quiz_attempts_count = fields.Integer(string="Number of times this user attempted the quiz") + class SlideLink(models.Model): _name = 'slide.slide.link' @@ -95,6 +97,7 @@ class Slide(models.Model): 'most_voted': 'likes desc', 'latest': 'date_published desc', } + _order = 'category_sequence asc, sequence asc' _sql_constraints = [ ('exclusion_html_content_and_url', "CHECK(html_content IS NULL OR url IS NULL)", "A slide is either filled with a document url or HTML content. Not both.") @@ -106,6 +109,8 @@ class Slide(models.Model): # description name = fields.Char('Title', required=True, translate=True) active = fields.Boolean(default=True) + sequence = fields.Integer('Sequence', default=10) + category_sequence = fields.Integer('Category sequence', related="category_id.sequence", store=True) user_id = fields.Many2one('res.users', string='Uploaded by', default=lambda self: self.env.uid) description = fields.Text('Description', translate=True) channel_id = fields.Many2one('slide.channel', string="Channel", required=True) @@ -126,15 +131,24 @@ class Slide(models.Model): partner_ids = fields.Many2many('res.partner', 'slide_slide_partner', 'slide_id', 'partner_id', string='Subscribers', groups='base.group_website_publisher') slide_partner_ids = fields.One2many('slide.slide.partner', 'slide_id', string='Subscribers information', groups='base.group_website_publisher') - user_membership_id = fields.Many2one('slide.slide.partner', string="Subscriber information", compute='_compute_user_membership_id', + user_membership_id = fields.Many2one( + 'slide.slide.partner', string="Subscriber information", compute='_compute_user_membership_id', help="Subscriber information for the current logged in user") + # Quiz related fields + question_ids = fields.One2many("slide.question","slide_id", string="Questions") + quiz_first_attempt_reward = fields.Integer("First attempt reward", default=10) + quiz_second_attempt_reward = fields.Integer("Second attempt reward", default=7) + quiz_third_attempt_reward = fields.Integer("Third attempt reward", default=5,) + quiz_fourth_attempt_reward = fields.Integer("Reward for every attempt after the third try", default=2) + # content slide_type = fields.Selection([ ('infographic', 'Infographic'), + ('webpage', 'Web Page'), ('presentation', 'Presentation'), ('document', 'Document'), - ('webpage', 'Web Page'), - ('video', 'Video')], + ('video', 'Video'), + ('quiz', "Quiz")], string='Type', required=True, default='document', readonly=True, help="The document type will be set automatically based on the document URL and properties (e.g. height and width for presentation and document).") |
