summaryrefslogtreecommitdiff
path: root/addons/website_slides/models
diff options
context:
space:
mode:
Diffstat (limited to 'addons/website_slides/models')
-rw-r--r--addons/website_slides/models/__init__.py1
-rw-r--r--addons/website_slides/models/slide_channel.py9
-rw-r--r--addons/website_slides/models/slide_question.py51
-rw-r--r--addons/website_slides/models/slide_slide.py22
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).")