[IMP] website_slides: duplicate course content

Purpose
=======
eLearning users may want to easily reuse a course to create a new one.
The user might want keep the section structure,
only part of the content and change the rest,
create an exact copy except documents are in another language,
or reuse a course for a few attendees.

Specifications
=============
Write copy_data function to add "copy" at the end of the name and
copying all the course content when duplicating a course.

Task-2704325

closes odoo/odoo#80980

Signed-off-by: Thibault Delavallee (tde) <tde@openerp.com>
This commit is contained in:
Fabio Barbero
2022-03-14 17:28:05 +00:00
parent afbc213e2c
commit 8b8eaba450
3 changed files with 16 additions and 7 deletions
+12 -3
View File
@@ -194,7 +194,7 @@ class Channel(models.Model):
'slide.channel.tag', 'slide_channel_tag_rel', 'channel_id', 'tag_id',
string='Tags', help='Used to categorize and filter displayed channels/courses')
# slides: promote, statistics
slide_ids = fields.One2many('slide.slide', 'channel_id', string="Slides and categories")
slide_ids = fields.One2many('slide.slide', 'channel_id', string="Slides and categories", copy=True)
slide_content_ids = fields.One2many('slide.slide', string='Content', compute="_compute_category_and_slide_ids")
slide_category_ids = fields.One2many('slide.slide', string='Categories', compute="_compute_category_and_slide_ids")
slide_last_update = fields.Date('Last Update', compute='_compute_slide_last_update', store=True)
@@ -209,8 +209,9 @@ class Channel(models.Model):
('none', 'None')],
string="Featured Content", default='latest', required=False,
help='Defines the content that will be promoted on the course home page',
copy=False,
)
promoted_slide_id = fields.Many2one('slide.slide', string='Promoted Slide')
promoted_slide_id = fields.Many2one('slide.slide', string='Promoted Slide', copy=False)
access_token = fields.Char("Security Token", copy=False, default=_default_access_token)
nbr_document = fields.Integer('Documents', compute='_compute_slides_statistics', store=True)
nbr_video = fields.Integer('Videos', compute='_compute_slides_statistics', store=True)
@@ -242,7 +243,7 @@ class Channel(models.Model):
enroll = fields.Selection([
('public', 'Public'), ('invite', 'On Invitation')],
default='public', string='Enroll Policy', required=True,
help='Defines how people can enroll to your Course.')
help='Defines how people can enroll to your Course.', copy=False)
enroll_msg = fields.Html(
'Enroll Message', help="Message explaining the enroll process",
default=_get_default_enroll_msg, translate=tools.html_translate, sanitize_attributes=False)
@@ -497,6 +498,14 @@ class Channel(models.Model):
return channels
def copy_data(self, default=None):
self.ensure_one()
default = default or {}
if 'name' not in default:
default['name'] = f"{self.name} ({_('copy')})"
return super().copy_data(default)
def write(self, vals):
# If description_short wasn't manually modified, there is an implicit link between this field and description.
if not is_html_empty(vals.get('description')) and is_html_empty(vals.get('description_short')) and self.description == self.description_short:
@@ -14,7 +14,7 @@ class SlideQuestion(models.Model):
sequence = fields.Integer("Sequence")
question = fields.Char("Question Name", required=True, translate=True)
slide_id = fields.Many2one('slide.slide', string="Content", required=True)
answer_ids = fields.One2many('slide.answer', 'question_id', string="Answer")
answer_ids = fields.One2many('slide.answer', 'question_id', string="Answer", copy=True)
# statistics
attempts_count = fields.Integer(compute='_compute_statistics', groups='website_slides.group_website_slides_officer')
attempts_avg = fields.Float(compute="_compute_statistics", digits=(6, 2), groups='website_slides.group_website_slides_officer')
+3 -3
View File
@@ -133,7 +133,7 @@ class Slide(models.Model):
user_vote = fields.Integer('User vote', compute='_compute_user_membership_id', compute_sudo=False)
user_has_completed = fields.Boolean('Is Member', compute='_compute_user_membership_id', compute_sudo=False)
# Quiz related fields
question_ids = fields.One2many("slide.question", "slide_id", string="Questions")
question_ids = fields.One2many("slide.question", "slide_id", string="Questions", copy=True)
questions_count = fields.Integer(string="Numbers of Questions", compute='_compute_questions_count')
quiz_first_attempt_reward = fields.Integer("Reward: first attempt", default=10)
quiz_second_attempt_reward = fields.Integer("Reward: second attempt", default=7)
@@ -155,7 +155,7 @@ class Slide(models.Model):
# generic
url = fields.Char('External URL', help="URL of the Google Drive file or URL of the YouTube video")
binary_content = fields.Binary('File', attachment=True)
slide_resource_ids = fields.One2many('slide.slide.resource', 'slide_id', string="Additional Resource for this slide")
slide_resource_ids = fields.One2many('slide.slide.resource', 'slide_id', string="Additional Resource for this slide", copy=True)
slide_resource_downloadable = fields.Boolean('Allow Download', default=False, help="Allow the user to download the content of the slide.")
# google
google_drive_id = fields.Char('Google Drive ID of the external URL', compute='_compute_google_drive_id')
@@ -196,7 +196,7 @@ class Slide(models.Model):
vimeo_id = fields.Char('Video Vimeo ID', compute='_compute_vimeo_id')
# website
website_id = fields.Many2one(related='channel_id.website_id', readonly=True)
date_published = fields.Datetime('Publish Date', readonly=True, tracking=False)
date_published = fields.Datetime('Publish Date', readonly=True, tracking=False, copy=False)
likes = fields.Integer('Likes', compute='_compute_like_info', store=True, compute_sudo=False)
dislikes = fields.Integer('Dislikes', compute='_compute_like_info', store=True, compute_sudo=False)
embed_code = fields.Html('Embed Code', readonly=True, compute='_compute_embed_code', sanitize=False)