diff --git a/document_page/__openerp__.py b/document_page/__openerp__.py
index 8c129f3e68a..a358f00a910 100644
--- a/document_page/__openerp__.py
+++ b/document_page/__openerp__.py
@@ -21,7 +21,7 @@
{
'name': 'Document Page',
- 'version': '9.0.1.0.1',
+ 'version': '9.0.2.0.0',
'category': 'Knowledge Management',
'author': 'OpenERP SA, Odoo Community Association (OCA)',
'images': ['images/category_list.png', 'images/create_category.png',
@@ -37,6 +37,10 @@
'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',
],
diff --git a/document_page/data/document_page.xml b/document_page/data/document_page.xml
deleted file mode 100644
index 9cd3c0dd5d0..00000000000
--- a/document_page/data/document_page.xml
+++ /dev/null
@@ -1,41 +0,0 @@
-
-
-
-
- The Odoo wiki
- help, quick start, wiki, formatting
- 0
- 1
- Initial Page
- == The Odoo wiki ==
-
-[[File:https://www.odoo.com/openerp_website/static/src/img/logo_transparent_198px.png Odoo]]
-
-The Odoo wiki allows you to manage your enterprise's contents using wiki
-restructured texts. This module provides a collaborative way to manage internal
-FAQs, quality manuals, technical references, etc.
-
-==Keypoints==
-* Same formating style than MediaWiki,
-* Any number of wiki group for different purposes,
-* Detailed history on all pages,
-* Integrated with the document management system.
-
-==Why you should use the OpenERP integrated wiki than a separate wiki system ?==
-* Allows links to any document of the system,
-* Uses the access controls of OpenERP for uniq access rights management,
-* Use it to describe projects, tasks, products,
-* Integrated with customer portal to provide restricted external accesses,
-* Linked to users processes for quality manuals.
-
-==To get more information==
-* [[Basic Wiki Editing]]
-* [[Wiki Documentation]]
-* [http://openerp.com The OpenERP website]
-
-
-
-
-
-
-
diff --git a/document_page/demo/document_page.xml b/document_page/demo/document_page.xml
index 8e6d2eca882..c9e0a042131 100644
--- a/document_page/demo/document_page.xml
+++ b/document_page/demo/document_page.xml
@@ -8,7 +8,7 @@
OpenERP Featurescategory
-
+
Summary of the feature
Long explanation
diff --git a/document_page/migrations/9.0.2.0.0/post-migration.py b/document_page/migrations/9.0.2.0.0/post-migration.py
new file mode 100644
index 00000000000..f590bbaa6da
--- /dev/null
+++ b/document_page/migrations/9.0.2.0.0/post-migration.py
@@ -0,0 +1,12 @@
+# -*- coding: utf-8 -*-
+# Copyright 2018 Ivan Todorovich
+# 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'
+ """)
diff --git a/document_page/models/document_page.py b/document_page/models/document_page.py
index ed7fc35cfd9..1d8d63fe670 100644
--- a/document_page/models/document_page.py
+++ b/document_page/models/document_page.py
@@ -18,10 +18,8 @@
# along with this program. If not, see .
#
##############################################################################
-import logging
-from openerp import models, fields, api
-_logger = logging.getLogger(__name__)
+from openerp import models, fields, api
class DocumentPage(models.Model):
@@ -54,18 +52,47 @@ class DocumentPage(models.Model):
)
content = fields.Text(
- "Content"
+ "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 10.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(
@@ -74,85 +101,88 @@ class DocumentPage(models.Model):
readonly=True
)
- create_date = fields.Datetime(
- "Created on",
+ content_date = fields.Datetime(
+ 'Last Contribution Date',
+ related='history_head.create_date',
+ store=True,
index=True,
- readonly=True
+ readonly=True,
)
- create_uid = fields.Many2one(
+ content_uid = fields.Many2one(
'res.users',
- 'Author',
+ 'Last Contributor',
+ related='history_head.create_uid',
+ store=True,
index=True,
- readonly=True
+ readonly=True,
)
- write_date = fields.Datetime(
- "Modification Date",
- index=True,
- readonly=True)
-
- write_uid = fields.Many2one(
- 'res.users',
- "Last Contributor",
- index=True,
- 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 += ["
" + self._get_page_index(subpage) +
- "
"]
+ for subpage in self.child_ids:
+ index += ["
" + subpage._get_page_index() + "
"]
r = ''
if link:
- r = '%s' % (page.id, page.name)
+ r = '%s' % (self.id, self.name)
if index:
r += "
" + "".join(index) + "
"
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 = '
'
- @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 == '
':
+ if self.parent_id and self.parent_id.type == "category":
+ self.content = self.parent_id.template
diff --git a/document_page/models/document_page_history.py b/document_page/models/document_page_history.py
index f296c0947d6..71535701e3d 100644
--- a/document_page/models/document_page_history.py
+++ b/document_page/models/document_page_history.py
@@ -18,11 +18,8 @@
# along with this program. If not, see .
#
##############################################################################
-import logging
import difflib
-from openerp import models, fields, _
-
-_logger = logging.getLogger(__name__)
+from openerp import models, fields, api, _
class DocumentPageHistory(models.Model):
@@ -31,24 +28,40 @@ class DocumentPageHistory(models.Model):
_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('