Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions document_page/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ Contributors

* Gervais Naoussi <[email protected]>
* Maxime Chambreuil <[email protected]>
* Iván Todorovich <[email protected]>

Funders
-------
Expand Down
7 changes: 5 additions & 2 deletions document_page/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

{
'name': 'Document Page',
'version': '10.0.1.0.0',
'version': '10.0.2.0.0',
'category': 'Knowledge Management',
'author': 'OpenERP SA, Odoo Community Association (OCA)',
'images': [
Expand All @@ -26,9 +26,12 @@
'wizard/document_page_create_menu.xml',
'wizard/document_page_show_diff.xml',
'views/document_page.xml',
'views/document_page_category.xml',
'views/document_page_history.xml',
'views/document_page_assets.xml',
'views/report_document_page.xml',
'security/document_page_security.xml',
'security/ir.model.access.csv',
'data/document_page.xml',
],
'demo': [
'demo/document_page.xml'
Expand Down
6 changes: 0 additions & 6 deletions document_page/data/document_page.xml

This file was deleted.

2 changes: 1 addition & 1 deletion document_page/demo/document_page.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<record id="demo_category1" model="document.page">
<field name="name">OpenERP Features</field>
<field name="type">category</field>
<field name="content">
<field name="template">
Summary of the feature

Long explanation
Expand Down
12 changes: 12 additions & 0 deletions document_page/migrations/10.0.2.0.0/post-migration.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# -*- coding: utf-8 -*-
# Copyright 2018 Ivan Todorovich <[email protected]>
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).


def migrate(cr, version): # pragma: no cover
# Set all pre-existing categories template to its content
cr.execute("""
UPDATE document_page
SET template = content
WHERE type = 'category'
""")
166 changes: 100 additions & 66 deletions document_page/models/document_page.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,8 @@
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import logging
from odoo import api, fields, models

_logger = logging.getLogger(__name__)


class DocumentPage(models.Model):
"""This class is use to manage Document."""
Expand Down Expand Up @@ -37,17 +34,48 @@ class DocumentPage(models.Model):
'Children'
)

content = fields.Text("Content")
content = fields.Text(
"Content",
compute='_compute_content',
inverse='_inverse_content',
search='_search_content',
required=True,
)

# no-op computed field
summary = fields.Char(
help='Describe the changes made',
compute=lambda x: x,
inverse=lambda x: x,
)

template = fields.Html(
"Template",
help="Template that will be used as a content template "
"for all new page of this category.",
)

# deprecated - should be removed on 11.0
# left here because some modules might still need it
display_content = fields.Text(
string='Displayed Content',
compute='_get_display_content'
compute='_compute_display_content'
)

history_head = fields.Many2one(
'document.page.history',
'HEAD',
compute='_compute_history_head',
store=True,
auto_join=True,
)

history_ids = fields.One2many(
'document.page.history',
'page_id',
'History'
'History',
order='create_date DESC',
readonly=True,
)

menu_id = fields.Many2one(
Expand All @@ -56,82 +84,88 @@ class DocumentPage(models.Model):
readonly=True
)

create_date = fields.Datetime(
"Created on",
readonly=True
content_date = fields.Datetime(
'Last Contribution Date',
related='history_head.create_date',
store=True,
index=True,
readonly=True,
)

create_uid = fields.Many2one(
content_uid = fields.Many2one(
'res.users',
'Author',
readonly=True
)

write_date = fields.Datetime(
"Modification Date",
readonly=True
'Last Contributor',
related='history_head.create_uid',
store=True,
index=True,
readonly=True,
)

write_uid = fields.Many2one(
'res.users',
"Last Contributor",
readonly=True
)

def _get_page_index(self, page, link=True):
@api.multi
def _get_page_index(self, link=True):
"""Return the index of a document."""
self.ensure_one()
index = []
for subpage in page.child_ids:
index += ["<li>" + self._get_page_index(subpage) +
"</li>"]
for subpage in self.child_ids:
index += ["<li>" + subpage._get_page_index() + "</li>"]
r = ''
if link:
r = '<a href="#id=%s">%s</a>' % (page.id, page.name)
r = '<a href="#id=%s">%s</a>' % (self.id, self.name)

if index:
r += "<ul>" + "".join(index) + "</ul>"
return r

def _get_display_content(self):
"""Return the content of a document."""
for page in self:
if page.type == "category":
display_content = self._get_page_index(page, link=False)
@api.multi
@api.depends('content')
def _compute_display_content(self):
# @deprecated, simply use content
for rec in self:
rec.display_content = rec.content

@api.multi
@api.depends('history_head', 'history_ids')
def _compute_content(self):
for rec in self:
if rec.type == 'category':
rec.content = rec._get_page_index(link=False)
else:
display_content = page.content
page.display_content = display_content
if rec.history_head:
rec.content = rec.history_head.content
else:
# html widget's default, so it doesn't trigger ghost save
rec.content = '<p><br></p>'

@api.onchange("parent_id")
def do_set_content(self):
"""We Set it the right content to the new parent."""
if self.parent_id and not self.content:
if self.parent_id.type == "category":
self.content = self.parent_id.content
@api.multi
def _inverse_content(self):
for rec in self:
if rec.type == 'content':
rec._create_history({
'content': rec.content,
'summary': rec.summary,
})

def create_history(self, page_id, content):
"""Create the first history of a newly created document."""
history = self.env['document.page.history']
return history.create({
"content": content,
"page_id": page_id
})
@api.multi
def _search_content(self, operator, value):
return [('history_head.content', operator, value)]

@api.multi
@api.depends('history_ids')
def _compute_history_head(self):
for rec in self:
if rec.history_ids:
rec.history_head = rec.history_ids[0]

@api.multi
def write(self, vals):
"""Write the content and set the history."""
result = super(DocumentPage, self).write(vals)
content = vals.get('content')
if content:
for page in self:
self.create_history(page.id, content)
return result

@api.model
@api.returns('self', lambda value: value.id)
def create(self, vals):
"""Create the first history of a document."""
page_id = super(DocumentPage, self).create(vals)
content = vals.get('content')
if content:
self.create_history(page_id.id, content)
return page_id
def _create_history(self, vals):
self.ensure_one()
history = self.env['document.page.history']
vals['page_id'] = self.id
return history.create(vals)

@api.onchange("parent_id")
def _onchange_parent_id(self):
"""We Set it the right content to the new parent."""
if not self.content or self.content == '<p><br></p>':
if self.parent_id and self.parent_id.type == "category":
self.content = self.parent_id.template
53 changes: 37 additions & 16 deletions document_page/models/document_page_history.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,38 +2,51 @@
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import logging
import difflib
from odoo import fields, models
from odoo import api, fields, models
from odoo.tools.translate import _

_logger = logging.getLogger(__name__)


class DocumentPageHistory(models.Model):
"""This model is necessary to manage a document history."""

_name = "document.page.history"
_description = "Document Page History"
_order = 'id DESC'
_rec_name = "create_date"

page_id = fields.Many2one('document.page', 'Page')
page_id = fields.Many2one('document.page', 'Page', ondelete='cascade')
summary = fields.Char('Summary', index=True)
content = fields.Text("Content")
create_date = fields.Datetime("Date")
create_uid = fields.Many2one('res.users', "Modified By")
diff = fields.Text(compute='_compute_diff')

@api.multi
@api.depends('content', 'page_id.history_ids')
def _compute_diff(self):
"""Shows a diff between this version and the previous version"""
history = self.env['document.page.history']
for rec in self:
prev = history.search([
('page_id', '=', rec.page_id.id),
('create_date', '<', rec.create_date)],
limit=1,
order='create_date DESC')
if prev:
rec.diff = self.getDiff(prev.id, rec.id)
else:
rec.diff = self.getDiff(False, rec.id)

@api.model
def getDiff(self, v1, v2):
"""Return the difference between two version of document version."""
text1 = self.browse(v1).content
text2 = self.browse(v2).content
line1 = line2 = ''
if text1:
line1 = text1.splitlines(1)
if text2:
line2 = text2.splitlines(1)
if (not line1 and not line2) or (line1 == line2):
text1 = v1 and self.browse(v1).content or ''
text2 = v2 and self.browse(v2).content or ''
# Include line breaks to make it more readable
# TODO: consider using a beautify library directly on the content
text1 = text1.replace('</p><p>', '</p>\r\n<p>')
text2 = text2.replace('</p><p>', '</p>\r\n<p>')
line1 = text1.splitlines(1)
line2 = text2.splitlines(1)
if line1 == line2:
return _('There are no changes in revisions.')
else:
diff = difflib.HtmlDiff()
Expand All @@ -43,3 +56,11 @@ def getDiff(self, v1, v2):
"Revision-{}".format(v2),
context=True
)

@api.multi
def name_get(self):
result = []
for rec in self:
name = "%s #%i" % (rec.page_id.name, rec.id)
result.append((rec.id, name))
return result
11 changes: 10 additions & 1 deletion document_page/security/document_page_security.xml
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>

<record id="knowledge.group_document_user" model="res.groups">
<record id="group_document_editor" model="res.groups">
<field name="name">Editor</field>
<field name="category_id" ref="knowledge.module_category_knowledge"/>
<field name="implied_ids" eval="[(4, ref('knowledge.group_document_user'))]"/>
</record>

<record id="group_document_manager" model="res.groups">
<field name="name">Manager</field>
<field name="category_id" ref="knowledge.module_category_knowledge"/>
<field name="implied_ids" eval="[(4, ref('group_document_editor'))]"/>
<field name="users" eval="[(4, ref('base.user_root'))]"/>
</record>

Expand Down
9 changes: 6 additions & 3 deletions document_page/security/ir.model.access.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
document_page_all,document.page,model_document_page,,1,0,0,0
document_page,document.page,model_document_page,base.group_user,1,1,1,1
document_page_history,document.page.history,model_document_page_history,base.group_user,1,0,1,0
document_page_user,document.page user,model_document_page,knowledge.group_document_user,1,0,0,0
document_page_history_user,document.page.history user,model_document_page_history,knowledge.group_document_user,1,0,0,0
document_page_editor,document.page editor,model_document_page,group_document_editor,1,1,1,0
document_page_history_editor,document.page.history editor,model_document_page_history,group_document_editor,1,1,1,0
document_page_manager,document.page manager,model_document_page,group_document_manager,1,1,1,1
document_page_history_manager,document.page.history manager,model_document_page_history,group_document_manager,1,1,1,0
Loading