From 8b8eaba450505b28078590edcd05445b2e80be30 Mon Sep 17 00:00:00 2001 From: Fabio Barbero Date: Tue, 7 Dec 2021 14:23:42 +0000 Subject: [PATCH] [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) --- addons/website_slides/models/slide_channel.py | 15 ++++++++++++--- addons/website_slides/models/slide_question.py | 2 +- addons/website_slides/models/slide_slide.py | 6 +++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index 507b13f695d..d95992f1637 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -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: diff --git a/addons/website_slides/models/slide_question.py b/addons/website_slides/models/slide_question.py index a08a2cf542b..e716f0d8f08 100644 --- a/addons/website_slides/models/slide_question.py +++ b/addons/website_slides/models/slide_question.py @@ -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') diff --git a/addons/website_slides/models/slide_slide.py b/addons/website_slides/models/slide_slide.py index 16e7039542d..a005f92ecc8 100644 --- a/addons/website_slides/models/slide_slide.py +++ b/addons/website_slides/models/slide_slide.py @@ -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)