[ADD] website_slides: merging slide.slide.link into resource
Purpose ======= This commit is used to merge 2 models into 1: `slide.slide.resource` and `slide.slide.link` Specifications ============== These models are merged in order to create a unique table for the *Additional Resources* of a Content. In order to do that, we merged the models into `slide.slide.resource` that will contain either a link or a file. task-2597345 See odoo/enterprise#20480 See odoo/upgrade#2784 Part-of: odoo/odoo#75646
This commit is contained in:
@@ -20,6 +20,7 @@
|
||||
</record>
|
||||
<!--RESOURCE-->
|
||||
<record id="slide_slide_demo_0_0_resource_0" model="slide.slide.resource">
|
||||
<field name="resource_type">file</field>
|
||||
<field name="name">Document</field>
|
||||
<field name="data" type="base64" file="website_slides/static/src/img/document.png"/>
|
||||
<field name="slide_id" ref="slide_slide_demo_0_0"/>
|
||||
@@ -186,18 +187,21 @@
|
||||
<field name="tag_ids" eval="[(4, ref('website_slides.slide_tag_demo_colorful')), (4, ref('website_slides.slide_tag_demo_theory'))]"/>
|
||||
<field name="description">Just some basics Energy Efficiency Facts.</field>
|
||||
</record>
|
||||
<record id="slide_slide_demo_1_2_link_0" model="slide.slide.link">
|
||||
<record id="slide_slide_demo_1_2_link_0" model="slide.slide.resource">
|
||||
<field name="resource_type">url</field>
|
||||
<field name="name">Energy Efficient Link 1</field>
|
||||
<field name="link">http://www.example.com</field>
|
||||
<field name="slide_id" ref="slide_slide_demo_1_2"/>
|
||||
</record>
|
||||
<record id="slide_slide_demo_1_2_link_1" model="slide.slide.link">
|
||||
<record id="slide_slide_demo_1_2_link_1" model="slide.slide.resource">
|
||||
<field name="resource_type">url</field>
|
||||
<field name="name">Energy Efficient Link 2</field>
|
||||
<field name="link">http://www.example.com</field>
|
||||
<field name="slide_id" ref="slide_slide_demo_1_2"/>
|
||||
</record>
|
||||
<!--RESOURCE-->
|
||||
<record id="slide_slide_demo_1_2_resource_0" model="slide.slide.resource">
|
||||
<field name="resource_type">file</field>
|
||||
<field name="name">Presentation</field>
|
||||
<field name="data" type="base64" file="website_slides/static/src/img/presentation.pdf"/>
|
||||
<field name="slide_id" ref="slide_slide_demo_1_2"/>
|
||||
@@ -263,12 +267,14 @@
|
||||
<field name="tag_ids" eval="[(4, ref('website_slides.slide_tag_demo_colorful'))]"/>
|
||||
<field name="description">We had a little chat with Harry Potted, sure he had interesting things to say !</field>
|
||||
</record>
|
||||
<record id="slide_slide_demo_1_4_link_0" model="slide.slide.link">
|
||||
<record id="slide_slide_demo_1_4_link_0" model="slide.slide.resource">
|
||||
<field name="resource_type">url</field>
|
||||
<field name="name">Know More Link 1</field>
|
||||
<field name="link">http://www.example.com</field>
|
||||
<field name="slide_id" ref="slide_slide_demo_1_4"/>
|
||||
</record>
|
||||
<record id="slide_slide_demo_1_4_link_1" model="slide.slide.link">
|
||||
<record id="slide_slide_demo_1_4_link_1" model="slide.slide.resource">
|
||||
<field name="resource_type">url</field>
|
||||
<field name="name">Know More Link 2</field>
|
||||
<field name="link">http://www.example.com</field>
|
||||
<field name="slide_id" ref="slide_slide_demo_1_4"/>
|
||||
@@ -389,18 +395,21 @@
|
||||
<field name="description">A summary of know-how: what are the main trees categories and how to differentiate them.</field>
|
||||
</record>
|
||||
<!-- LINKS -->
|
||||
<record id="slide_slide_demo_2_0_link_0" model="slide.slide.link">
|
||||
<record id="slide_slide_demo_2_0_link_0" model="slide.slide.resource">
|
||||
<field name="resource_type">url</field>
|
||||
<field name="name">Trees Classification Link</field>
|
||||
<field name="link">http://www.example.com</field>
|
||||
<field name="slide_id" ref="slide_slide_demo_2_0"/>
|
||||
</record>
|
||||
<record id="slide_slide_demo_2_0_link_1" model="slide.slide.link">
|
||||
<record id="slide_slide_demo_2_0_link_1" model="slide.slide.resource">
|
||||
<field name="resource_type">url</field>
|
||||
<field name="name">Main types of trees Link</field>
|
||||
<field name="link">http://www.example.com</field>
|
||||
<field name="slide_id" ref="slide_slide_demo_2_0"/>
|
||||
</record>
|
||||
<!--RESOURCE-->
|
||||
<record id="slide_slide_demo_2_0_resource_0" model="slide.slide.resource">
|
||||
<field name="resource_type">file</field>
|
||||
<field name="name">Tree image</field>
|
||||
<field name="data" type="base64" file="website_slides/static/src/img/slide_demo_tree_img_2.jpg"/>
|
||||
<field name="slide_id" ref="slide_slide_demo_2_0"/>
|
||||
@@ -742,12 +751,14 @@
|
||||
<field name="tag_ids" eval="[(4, ref('website_slides.slide_tag_demo_tools'))]"/>
|
||||
<field name="description">Tools you will need to complete this course.</field>
|
||||
</record>
|
||||
<record id="slide_slide_demo_5_0_link_0" model="slide.slide.link">
|
||||
<record id="slide_slide_demo_5_0_link_0" model="slide.slide.resource">
|
||||
<field name="resource_type">url</field>
|
||||
<field name="name">Example Link 1</field>
|
||||
<field name="link">http://www.example.com</field>
|
||||
<field name="slide_id" ref="slide_slide_demo_5_0"/>
|
||||
</record>
|
||||
<record id="slide_slide_demo_5_0_link_1" model="slide.slide.link">
|
||||
<record id="slide_slide_demo_5_0_link_1" model="slide.slide.resource">
|
||||
<field name="resource_type">url</field>
|
||||
<field name="name">Example Link 2</field>
|
||||
<field name="link">http://www.example.com</field>
|
||||
<field name="slide_id" ref="slide_slide_demo_5_0"/>
|
||||
|
||||
@@ -7,6 +7,7 @@ from . import slide_slide
|
||||
from . import slide_question
|
||||
from . import slide_channel
|
||||
from . import slide_channel_tag
|
||||
from . import slide_slide_resource
|
||||
from . import res_config_settings
|
||||
from . import website
|
||||
from . import res_users
|
||||
|
||||
@@ -55,25 +55,6 @@ class SlidePartnerRelation(models.Model):
|
||||
('partner_id', 'in', self.partner_id.ids),
|
||||
])._recompute_completion()
|
||||
|
||||
|
||||
class SlideLink(models.Model):
|
||||
_name = 'slide.slide.link'
|
||||
_description = "External URL for a particular slide"
|
||||
|
||||
slide_id = fields.Many2one('slide.slide', required=True, ondelete='cascade')
|
||||
name = fields.Char('Title', required=True)
|
||||
link = fields.Char('Link', required=True)
|
||||
|
||||
|
||||
class SlideResource(models.Model):
|
||||
_name = 'slide.slide.resource'
|
||||
_description = "Additional resource for a particular slide"
|
||||
|
||||
slide_id = fields.Many2one('slide.slide', required=True, ondelete='cascade')
|
||||
name = fields.Char('Name', required=True)
|
||||
data = fields.Binary('Resource'
|
||||
|
||||
|
||||
class EmbeddedSlide(models.Model):
|
||||
""" Embedding in third party websites. Track view count, generate statistics. """
|
||||
_name = 'slide.embed'
|
||||
@@ -173,7 +154,6 @@ class Slide(models.Model):
|
||||
datas = fields.Binary('File', attachment=True)
|
||||
url = fields.Char('Document URL', help="Youtube or Google Document URL")
|
||||
document_id = fields.Char('Document ID', help="Youtube or Google Document ID")
|
||||
link_ids = fields.One2many('slide.slide.link', 'slide_id', string="External URL for this slide")
|
||||
slide_resource_ids = fields.One2many('slide.slide.resource', 'slide_id', string="Additional Resource for this slide")
|
||||
slide_resource_downloadable = fields.Boolean('Allow Download', default=True, help="Allow the user to download the content of the slide.")
|
||||
mime_type = fields.Char('Mime-type')
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
# -*- 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 SlideResource(models.Model):
|
||||
_name = 'slide.slide.resource'
|
||||
_description = "Additional resource for a particular slide"
|
||||
|
||||
slide_id = fields.Many2one('slide.slide', required=True, ondelete='cascade')
|
||||
resource_type = fields.Selection([('file', 'File'), ('url', 'Link')], required=True)
|
||||
name = fields.Char('Name', compute="_compute_name", readonly=False, store=True)
|
||||
data = fields.Binary('Resource', compute='_compute_reset_resources', store=True, readonly=False)
|
||||
file_name = fields.Char(store=True)
|
||||
link = fields.Char('Link', compute='_compute_reset_resources', store=True, readonly=False)
|
||||
|
||||
_sql_constraints = [
|
||||
('check_url', "CHECK (resource_type != 'url' OR link IS NOT NULL)", 'A resource of type url must contain a link.'),
|
||||
('check_file_type', "CHECK (resource_type != 'file' OR link IS NULL)", 'A resource of type file cannot contain a link.'),
|
||||
]
|
||||
|
||||
@api.depends('resource_type')
|
||||
def _compute_reset_resources(self):
|
||||
for resource in self:
|
||||
if resource.resource_type == 'file':
|
||||
resource.link = False
|
||||
resource.data = resource.data
|
||||
else:
|
||||
resource.data = False
|
||||
resource.link = resource.link
|
||||
|
||||
@api.depends('file_name', 'resource_type', 'data', 'link')
|
||||
def _compute_name(self):
|
||||
for resource in self:
|
||||
to_update = not resource.name or resource.name == _("Resource")
|
||||
if to_update:
|
||||
new_name = _("Resource")
|
||||
if resource.resource_type == 'file' and (resource.data or resource.file_name):
|
||||
new_name = self.file_name
|
||||
elif resource.resource_type == 'url':
|
||||
new_name = self.link
|
||||
resource.name = new_name
|
||||
|
||||
@api.constrains('data')
|
||||
def _check_link_type(self):
|
||||
for record in self:
|
||||
if record.resource_type != 'file' and record.data:
|
||||
raise ValidationError(_("Resource %(resource_name)s is a link and should not contain a data file", resource_name=record.name))
|
||||
@@ -21,8 +21,6 @@ access_slide_channel_partners_all,slide.channel.users.all,model_slide_channel_pa
|
||||
access_slide_channel_partners_system,slide.channel.users.system,model_slide_channel_partner,website_slides.group_website_slides_officer,1,1,1,1
|
||||
access_slide_embed_all,slide.embed.all,model_slide_embed,,1,0,0,0
|
||||
access_slide_embed_user,slide.embed.user,model_slide_embed,base.group_user,1,1,1,1
|
||||
access_slide_slide_link_all,slide.slide.link.all,model_slide_slide_link,,1,0,0,0
|
||||
access_slide_slide_link_officer,slide.slide.link.officer,model_slide_slide_link,website_slides.group_website_slides_officer,1,1,1,1
|
||||
access_slide_slide_resource_all,slide.slide.resource.all,model_slide_slide_resource,,1,0,0,0
|
||||
access_slide_slide_resource_public,slide.slide.resource.public,model_slide_slide_resource,base.group_public,0,0,0,0
|
||||
access_slide_slide_resource_publisher,slide.slide.resource.publisher,model_slide_slide_resource,website_slides.group_website_slides_officer,1,1,1,1
|
||||
|
||||
|
@@ -198,5 +198,16 @@
|
||||
<field name="perm_create" eval="False"/>
|
||||
<field name="perm_unlink" eval="False"/>
|
||||
</record>
|
||||
|
||||
<record id="rule_slide_slide_resource_downloadable_manager" model="ir.rule">
|
||||
<field name="name">Resource: manager: crud all</field>
|
||||
<field name="model_id" ref="model_slide_slide_resource"/>
|
||||
<field name="domain_force">[(1, '=', 1)]</field>
|
||||
<field name="groups" eval="[(4, ref('group_website_slides_manager'))]"/>
|
||||
<field name="perm_read" eval="1"/>
|
||||
<field name="perm_write" eval="1"/>
|
||||
<field name="perm_create" eval="1"/>
|
||||
<field name="perm_unlink" eval="1"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
from . import common
|
||||
from . import test_karma
|
||||
from . import test_resources
|
||||
from . import test_security
|
||||
from . import test_slide_utils
|
||||
from . import test_statistics
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from psycopg2 import IntegrityError
|
||||
|
||||
from odoo.addons.website_slides.tests import common
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tests.common import users
|
||||
from odoo.tools import mute_logger
|
||||
|
||||
|
||||
class TestResources(common.SlidesCase):
|
||||
|
||||
@users('user_officer')
|
||||
@mute_logger('odoo')
|
||||
def test_constraints(self):
|
||||
self.link = self.env["slide.slide.resource"].create({
|
||||
'name': 'Test Link',
|
||||
'resource_type': 'url',
|
||||
'link': 'https://www.example.com',
|
||||
'slide_id': self.slide.id,
|
||||
})
|
||||
|
||||
self.resource = self.env["slide.slide.resource"].create({
|
||||
'name': 'Test Resource',
|
||||
'resource_type': 'file',
|
||||
'data': '1111',
|
||||
'slide_id': self.slide.id,
|
||||
})
|
||||
|
||||
self.assertEqual(len(self.slide.slide_resource_ids), 2)
|
||||
with self.assertRaises(ValidationError, msg="Cannot have a type link with a file"):
|
||||
self.env["slide.slide.resource"].create({
|
||||
'name': 'Raise Error Test Resource',
|
||||
'resource_type': 'url',
|
||||
'link': '1111',
|
||||
'data': '1111',
|
||||
'slide_id': self.slide.id,
|
||||
})
|
||||
self.assertEqual(len(self.slide.slide_resource_ids), 2)
|
||||
with self.assertRaises(IntegrityError, msg="Cannot have a type file with a link"):
|
||||
self.env["slide.slide.resource"].create({
|
||||
'name': 'Raise Error Test File With Link',
|
||||
'resource_type': 'file',
|
||||
'link': '1111',
|
||||
'slide_id': self.slide.id,
|
||||
})
|
||||
with self.assertRaises(IntegrityError, msg="Cannot have an empty link"):
|
||||
self.env["slide.slide.resource"].create({
|
||||
'name': 'Raise Error Test Empty URL',
|
||||
'resource_type': 'url',
|
||||
'slide_id': self.slide.id,
|
||||
})
|
||||
@@ -139,7 +139,7 @@
|
||||
<field name="slide_resource_ids" widget="one2many" nolabel="1">
|
||||
<tree editable="top">
|
||||
<field name="resource_type"/>
|
||||
<field name="name"/>
|
||||
<field name="name" required="1"/>
|
||||
<field name="file_name" invisible="1"/>
|
||||
<field name="data" attrs="{'readonly': [('resource_type', '=', 'url')]}" filename="file_name"/>
|
||||
<field name="link" string="Link"
|
||||
|
||||
@@ -162,10 +162,10 @@
|
||||
</span>
|
||||
</div>
|
||||
</a>
|
||||
<ul t-if="aside_slide.link_ids or aside_slide.slide_resource_ids or aside_slide.question_ids" class="list-group px-2 mb-1 list-unstyled">
|
||||
<t t-foreach="aside_slide.link_ids" t-as="resource">
|
||||
<ul t-if="aside_slide.slide_resource_ids or aside_slide.question_ids" class="list-group px-2 mb-1 list-unstyled">
|
||||
<t t-foreach="aside_slide.slide_resource_ids" t-as="resource">
|
||||
<li class="pl-4">
|
||||
<a t-if="can_access" t-att-href="resource.link" target="new" class="text-decoration-none small">
|
||||
<a t-if="can_access and resource.link" t-att-href="resource.link" target="new" class="text-decoration-none small">
|
||||
<i class="fa fa-link mr-1"/><span t-field="resource.name"/>
|
||||
</a>
|
||||
<span t-else="" class="text-decoration-none text-muted small">
|
||||
@@ -410,21 +410,23 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mt-3 mb-3">
|
||||
<div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0" t-if="len(slide.link_ids)">
|
||||
<span t-if="slide.link_ids" class="text-muted font-weight-bold mr-3">External sources</span>
|
||||
<t t-set="links" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'url')"/>
|
||||
<t t-set="files" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'file' and res.data)"/>
|
||||
<div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0" t-if="links">
|
||||
<span class="text-muted font-weight-bold mr-3">External sources</span>
|
||||
<div class="text-muted mr-auto border-left pl-3">
|
||||
<t t-foreach="slide.link_ids" t-as="link">
|
||||
<t t-foreach="links" t-as="link">
|
||||
<a t-att-href="link.link" t-esc="link.name"/><br />
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
<group>
|
||||
<div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0 o_wslides_js_course_join" t-if="len(slide.slide_resource_ids)">
|
||||
<div class="col-12 col-md d-flex align-items-start mb-4 mb-md-0 o_wslides_js_course_join" t-if="files">
|
||||
<span t-if="slide.channel_id.is_member or slide.channel_id.can_publish or slide.is_preview or slide.channel_id.enroll in ['private', 'payment']" class="text-muted font-weight-bold mr-3">
|
||||
Additional Resources
|
||||
</span>
|
||||
<div t-if="slide.channel_id.is_member or slide.channel_id.can_publish" class="text-muted mr-auto border-left pl-3">
|
||||
<t t-foreach="slide.slide_resource_ids" t-as="resource">
|
||||
<t t-foreach="files" t-as="resource">
|
||||
<a t-attf-href="/web/content/slide.slide.resource/#{resource.id}/data?download=true" t-esc="resource.name"/><br />
|
||||
</t>
|
||||
</div>
|
||||
|
||||
@@ -135,18 +135,20 @@
|
||||
<div class="o_wslides_fs_slide_name text-600" t-esc="slide.name"/>
|
||||
</div>
|
||||
</span>
|
||||
<ul class="list-unstyled w-100 pt-2 small" t-if="slide.link_ids or slide.slide_resource_ids or (slide.question_ids and not slide.slide_type =='quiz')" >
|
||||
<li t-if="slide.link_ids" t-foreach="slide.link_ids" t-as="link" class="pl-0 mb-1">
|
||||
<ul class="list-unstyled w-100 pt-2 small" t-if="slide.slide_resource_ids or (slide.question_ids and not slide.slide_type =='quiz')" >
|
||||
<t t-set="links" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'url')"/>
|
||||
<li t-if="links" t-foreach="links" t-as="link" class="pl-0 mb-1">
|
||||
<a t-if="can_access" class="o_wslides_fs_slide_link" t-att-href="link.link" target="_blank">
|
||||
<i class="fa fa-link mr-2"/><span t-esc="link.name"/>
|
||||
</a>
|
||||
<span t-else="" class="o_wslides_fs_slide_link text-600">
|
||||
<i class="fa fa-link mr-2"/><span t-esc="link.name"/>
|
||||
<i class="fa fa-link mr-2"/><span t-esc="resource.name"/>
|
||||
</span>
|
||||
</li>
|
||||
<div class="o_wslides_js_course_join pl-0" t-if="slide.slide_resource_ids">
|
||||
<t t-set="resources" t-value="slide.slide_resource_ids.filtered(lambda res: res.resource_type == 'file')"/>
|
||||
<div class="o_wslides_js_course_join pl-0" t-if="resources">
|
||||
<t t-if="is_member or slide.channel_id.can_publish">
|
||||
<li t-foreach="slide.slide_resource_ids" t-as="resource" class="mb-1">
|
||||
<li t-foreach="resources" t-as="resource" class="mb-1">
|
||||
<a class="o_wslides_fs_slide_link" t-attf-href="/web/content/slide.slide.resource/#{resource.id}/data?download=true">
|
||||
<i class="fa fa-download mr-2"/><span t-esc="resource.name"/>
|
||||
</a>
|
||||
|
||||
Reference in New Issue
Block a user