diff --git a/document_page_approval/__init__.py b/document_page_approval/__init__.py
new file mode 100644
index 00000000..d2b3bb9e
--- /dev/null
+++ b/document_page_approval/__init__.py
@@ -0,0 +1,21 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2013 Savoir-faire Linux ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+from . import document_page_approval
diff --git a/document_page_approval/__openerp__.py b/document_page_approval/__openerp__.py
new file mode 100644
index 00000000..6c2b3e1a
--- /dev/null
+++ b/document_page_approval/__openerp__.py
@@ -0,0 +1,63 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2013 Savoir-faire Linux ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+{
+ 'name': 'Document Page Approval',
+ 'version': '8.0.1.0.0',
+ "author": "Savoir-faire Linux,Odoo Community Association (OCA)",
+ "website": "http://www.savoirfairelinux.com",
+ "license": "AGPL-3",
+ 'category': 'Knowledge Management',
+ 'description': """
+This module adds a workflow to approve page modification and show the approved
+version by default.
+
+Scenario
+========
+
+* Set a valid email address on the company settings.
+* Create a new page category and set an approver group. Make sure users
+ belonging to that group have valid email addresses.
+* Create a new page and choose the previously created category.
+* A notification is sent to the group with a link to the page history to
+ review.
+* Depending on the review, the page history is approved or not.
+* Users reading the page see the last approved version.
+ """,
+ 'depends': [
+ 'document_page',
+ 'email_template',
+ ],
+ 'data': [
+ 'data/email_template.xml',
+ 'document_page_wkfl.xml',
+ 'document_page_view.xml',
+ 'security/document_page_security.xml',
+ 'security/ir.model.access.csv',
+ ],
+ 'installable': True,
+ 'auto_install': False,
+ 'images': [
+ 'images/category.png',
+ 'images/page_history_list.png',
+ 'images/page_history.png',
+ ],
+}
diff --git a/document_page_approval/data/email_template.xml b/document_page_approval/data/email_template.xml
new file mode 100644
index 00000000..af77719d
--- /dev/null
+++ b/document_page_approval/data/email_template.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+ Automated new draft need approval Notification Mail
+ ${object.create_uid.company_id.email or 'noreply@localhost.com'}
+ New version of "${object.page_id.name}" to approve
+ ${object.get_approvers_email}
+
+
+ ${object.create_uid.partner_id.lang}
+ Hello,
+
+The page "${object.page_id.name}" has been modified and need your approval.
+
+You can review the new version here : ${object.get_page_url}
+
+Have a great day.
+--
+OpenERP
]]>
+
+
+
+
+
diff --git a/document_page_approval/document_page_approval.py b/document_page_approval/document_page_approval.py
new file mode 100644
index 00000000..1d5002d5
--- /dev/null
+++ b/document_page_approval/document_page_approval.py
@@ -0,0 +1,258 @@
+# -*- encoding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2013 Savoir-faire Linux ().
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as
+# published by the Free Software Foundation, either version 3 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see .
+#
+##############################################################################
+
+from datetime import datetime
+from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT
+from openerp import models, fields
+
+
+class document_page_history_wkfl(models.Model):
+ _inherit = 'document.page.history'
+
+ def page_approval_draft(self, cr, uid, ids, context=None):
+ self.write(cr, uid, ids, {'state': 'draft'})
+ template_id = self.pool.get('ir.model.data').get_object_reference(
+ cr, uid,
+ 'document_page_approval',
+ 'email_template_new_draft_need_approval')[1]
+ for page in self.browse(cr, uid, ids, context=context):
+ if page.is_parent_approval_required:
+ self.pool.get('email.template').send_mail(
+ cr,
+ uid,
+ template_id,
+ page.id,
+ force_send=True
+ )
+ return True
+
+ def page_approval_approved(self, cr, uid, ids, context=None):
+ self.write(cr, uid, ids, {
+ 'state': 'approved',
+ 'approved_date': datetime.now().strftime(
+ DEFAULT_SERVER_DATETIME_FORMAT),
+ 'approved_uid': uid
+ }, context=context)
+ return True
+
+ def _can_user_approve_page(self):
+ user = self.env.user
+ for page in self:
+ page.can_user_approve_page = page.can_user_approve_this_page(
+ page.page_id,
+ user
+ )
+
+ def can_user_approve_this_page(self, page, user):
+ if page:
+ res = page.approver_gid in user.groups_id
+ res = res or self.can_user_approve_this_page(page.parent_id, user)
+ else:
+ res = False
+ return res
+
+ def get_approvers_guids(self):
+ res = {}
+ for page in self:
+ res[page.id] = self.get_approvers_guids_for_page(page.page_id)
+ return res
+
+ def get_approvers_guids_for_page(self, page):
+ if page:
+ if page.approver_gid:
+ res = [page.approver_gid.id]
+ else:
+ res = []
+ res.extend(self.get_approvers_guids_for_page(page.parent_id))
+ else:
+ res = []
+
+ return res
+
+ def _get_approvers_email(self):
+ for page in self:
+ emails = ''
+ guids = self.get_approvers_guids()
+ uids = [i.id for i in self.env['res.users'].search([
+ ('groups_id', 'in', guids[page.id])
+ ])]
+ users = self.env['res.users'].browse(uids)
+
+ for user in users:
+ if user.email:
+ emails += user.email
+ emails += ','
+ else:
+ empl = self.env['hr.employee'].search([
+ ('login', '=', user.login)
+ ])
+ if empl.work_email:
+ emails += empl.work_email
+ emails += ','
+
+ page.get_approvers_email = emails[:-1]
+
+ def _get_page_url(self):
+ for page in self:
+ base_url = self.env['ir.config_parameter'].get_param(
+ 'web.base.url',
+ default='http://localhost:8069'
+ )
+
+ page.get_page_url = (
+ '{}/#db={}&id={}&view_type=form&'
+ 'model=document.page.history').format(
+ base_url,
+ self.env.cr.dbname,
+ page.id
+ )
+
+ state = fields.Selection(
+ [('draft', 'Draft'), ('approved', 'Approved')],
+ 'Status',
+ readonly=True
+ )
+
+ approved_date = fields.Datetime("Approved Date")
+
+ approved_uid = fields.Many2one(
+ 'res.users',
+ "Approved By"
+ )
+
+ is_parent_approval_required = fields.Boolean(
+ related='page_id.is_parent_approval_required',
+ string="parent approval",
+ store=False
+ )
+
+ can_user_approve_page = fields.Boolean(
+ compute=_can_user_approve_page,
+ string="can user approve this page",
+ store=False
+ )
+ get_approvers_email = fields.Text(
+ compute=_get_approvers_email,
+ string="get all approvers email",
+ store=False
+ )
+ get_page_url = fields.Text(
+ compute=_get_page_url,
+ string="URL",
+ store=False
+ )
+
+
+class document_page_approval(models.Model):
+ _inherit = 'document.page'
+
+ def _get_display_content(self):
+ for page in self:
+ content = ""
+ if page.type == "category":
+ content = self._get_page_index(page, link=False)
+ else:
+ history = self.env['document.page.history']
+ if self.is_approval_required(page):
+ history_ids = history.search(
+ [
+ ('page_id', '=', page.id),
+ ('state', '=', 'approved')
+ ],
+ limit=1,
+ order='create_date DESC'
+ )
+ content = history_ids.content
+ else:
+ content = page.content
+ page.display_content = content
+
+ def _get_approved_date(self):
+ for page in self:
+ approved_date = False
+ if self.is_approval_required(page):
+ history = self.env['document.page.history']
+ history_ids = history.search(
+ [
+ ('page_id', '=', page.id),
+ ('state', '=', 'approved')
+ ],
+ limit=1,
+ order='create_date DESC'
+ )
+ approved_date = history_ids.approved_date
+ page.approved_date = approved_date
+
+ def _get_approved_uid(self):
+ for page in self:
+ approved_uid = False
+ if self.is_approval_required(page):
+ history = self.env['document.page.history']
+ history_ids = history.search(
+ [
+ ('page_id', '=', page.id),
+ ('state', '=', 'approved')
+ ],
+ limit=1,
+ order='create_date DESC'
+ )
+ approved_uid = history_ids.approved_uid.id
+ page.approved_uid = approved_uid
+
+ def _is_parent_approval_required(self):
+ for page in self:
+ page.is_parent_approval_required = self.is_approval_required(page)
+
+ def is_approval_required(self, page):
+ if page:
+ res = page.approval_required
+ res = res or self.is_approval_required(page.parent_id)
+ else:
+ res = False
+ return res
+
+ display_content = fields.Text(
+ compute=_get_display_content,
+ string='Displayed Content'
+ )
+
+ approved_date = fields.Datetime(
+ compute=_get_approved_date,
+ string="Approved Date"
+ )
+
+ approved_uid = fields.Many2one(
+ 'res.users',
+ compute=_get_approved_uid,
+ string="Approved By",
+ )
+
+ approval_required = fields.Boolean("Require approval")
+
+ is_parent_approval_required = fields.Boolean(
+ compute=_is_parent_approval_required,
+ string="parent approval"
+ )
+
+ approver_gid = fields.Many2one(
+ "res.groups",
+ "Approver group"
+ )
diff --git a/document_page_approval/document_page_view.xml b/document_page_approval/document_page_view.xml
new file mode 100644
index 00000000..3cf9e574
--- /dev/null
+++ b/document_page_approval/document_page_view.xml
@@ -0,0 +1,70 @@
+
+
+
+
+ document.page.history.form
+ document.page.history
+
+
+
+
+
+
+
+
+
+ document.page.form
+ document.page
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ document.page.history.tree
+ document.page.history
+
+
+
+
+
+
+
+
+
+
diff --git a/document_page_approval/document_page_wkfl.xml b/document_page_approval/document_page_wkfl.xml
new file mode 100644
index 00000000..a4a94b14
--- /dev/null
+++ b/document_page_approval/document_page_wkfl.xml
@@ -0,0 +1,43 @@
+
+
+
+
+
+ document.page.history.aproval.wkf
+ document.page.history
+ True
+
+
+
+
+ True
+ draft
+ function
+ page_approval_draft()
+
+
+
+
+ approved
+ function
+ page_approval_approved()
+ True
+
+
+
+
+
+ page_approval_approve
+
+
+
+
+
+ edit
+
+
+
+
+
diff --git a/document_page_approval/i18n/document_page_approval.pot b/document_page_approval/i18n/document_page_approval.pot
new file mode 100644
index 00000000..4ddc9733
--- /dev/null
+++ b/document_page_approval/i18n/document_page_approval.pot
@@ -0,0 +1,110 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * document_page_approval
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-19 03:58+0000\n"
+"PO-Revision-Date: 2013-07-19 03:58+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: document_page_approval
+#: field:document.page.history,state:0
+msgid "Status"
+msgstr ""
+
+#. module: document_page_approval
+#: field:document.page,approval_required:0
+msgid "Require approval"
+msgstr ""
+
+#. module: document_page_approval
+#: field:document.page,is_parent_approval_required:0
+#: field:document.page.history,is_parent_approval_required:0
+msgid "parent approval"
+msgstr ""
+
+#. module: document_page_approval
+#: model:email.template,body_html:document_page_approval.email_template_new_draft_need_approval
+msgid "\n"
+"Hello,
\n"
+"\n"
+"The page \"${object.page_id.name}\" has been modified and need your approval.
\n"
+"\n"
+"You can review the new version here : ${object.get_page_url}
\n"
+" \n"
+"Have a great day.
\n"
+"--
\n"
+"OpenERP
\n"
+" "
+msgstr ""
+
+#. module: document_page_approval
+#: model:ir.model,name:document_page_approval.model_document_page
+msgid "Document Page"
+msgstr ""
+
+#. module: document_page_approval
+#: field:document.page,approved_uid:0
+#: field:document.page.history,approved_uid:0
+msgid "Approved By"
+msgstr ""
+
+#. module: document_page_approval
+#: model:email.template,subject:document_page_approval.email_template_new_draft_need_approval
+msgid "New version of \"${object.page_id.name}\" to approve"
+msgstr ""
+
+#. module: document_page_approval
+#: selection:document.page.history,state:0
+msgid "Draft"
+msgstr ""
+
+#. module: document_page_approval
+#: field:document.page.history,get_page_url:0
+msgid "URL"
+msgstr ""
+
+#. module: document_page_approval
+#: field:document.page,approved_date:0
+#: field:document.page.history,approved_date:0
+msgid "Approved Date"
+msgstr ""
+
+#. module: document_page_approval
+#: field:document.page.history,can_user_approve_page:0
+msgid "can user approve this page"
+msgstr ""
+
+#. module: document_page_approval
+#: field:document.page,approver_gid:0
+msgid "Approver group"
+msgstr ""
+
+#. module: document_page_approval
+#: model:ir.model,name:document_page_approval.model_document_page_history
+msgid "Document Page History"
+msgstr ""
+
+#. module: document_page_approval
+#: view:document.page.history:0
+msgid "Approve"
+msgstr ""
+
+#. module: document_page_approval
+#: selection:document.page.history,state:0
+msgid "Approved"
+msgstr ""
+
+#. module: document_page_approval
+#: field:document.page.history,get_approvers_email:0
+msgid "get all approvers email"
+msgstr ""
+
diff --git a/document_page_approval/i18n/fr.po b/document_page_approval/i18n/fr.po
new file mode 100644
index 00000000..26573fa4
--- /dev/null
+++ b/document_page_approval/i18n/fr.po
@@ -0,0 +1,119 @@
+# Translation of OpenERP Server.
+# This file contains the translation of the following modules:
+# * document_page_approval
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: OpenERP Server 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2013-07-19 03:58+0000\n"
+"PO-Revision-Date: 2013-07-19 03:58+0000\n"
+"Last-Translator: <>\n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: \n"
+"Plural-Forms: \n"
+
+#. module: document_page_approval
+#: field:document.page.history,state:0
+msgid "Status"
+msgstr "Statut"
+
+#. module: document_page_approval
+#: field:document.page,approval_required:0
+msgid "Require approval"
+msgstr "Nécessite une approbation"
+
+#. module: document_page_approval
+#: field:document.page,is_parent_approval_required:0
+#: field:document.page.history,is_parent_approval_required:0
+msgid "parent approval"
+msgstr "Approbation parente"
+
+#. module: document_page_approval
+#: model:email.template,body_html:document_page_approval.email_template_new_draft_need_approval
+msgid "\n"
+"Hello,
\n"
+"\n"
+"The page \"${object.page_id.name}\" has been modified and need your approval.
\n"
+"\n"
+"You can review the new version here : ${object.get_page_url}
\n"
+" \n"
+"Have a great day.
\n"
+"--
\n"
+"OpenERP
\n"
+" "
+msgstr "\n"
+"Bonjour,
\n"
+"\n"
+"La page \"${object.page_id.name}\" a été modifié et demande votre approbation.
\n"
+"\n"
+"Vous pouvez réviser la nouvelle version ici : ${object.get_page_url}
\n"
+" \n"
+"Bonne journée.
\n"
+"--
\n"
+"OpenERP
\n"
+" "
+
+#. module: document_page_approval
+#: model:ir.model,name:document_page_approval.model_document_page
+msgid "Document Page"
+msgstr "Page"
+
+#. module: document_page_approval
+#: field:document.page,approved_uid:0
+#: field:document.page.history,approved_uid:0
+msgid "Approved By"
+msgstr "Approuvée par"
+
+#. module: document_page_approval
+#: model:email.template,subject:document_page_approval.email_template_new_draft_need_approval
+msgid "New version of \"${object.page_id.name}\" to approve"
+msgstr "Nouvelle version de \"${object.page_id.name}\" à approuver"
+
+#. module: document_page_approval
+#: selection:document.page.history,state:0
+msgid "Draft"
+msgstr "Brouillon"
+
+#. module: document_page_approval
+#: field:document.page.history,get_page_url:0
+msgid "URL"
+msgstr "URL"
+
+#. module: document_page_approval
+#: field:document.page,approved_date:0
+#: field:document.page.history,approved_date:0
+msgid "Approved Date"
+msgstr "Date d'approbation"
+
+#. module: document_page_approval
+#: field:document.page.history,can_user_approve_page:0
+msgid "can user approve this page"
+msgstr "Est-ce que l'usager peut approuver cette page ?"
+
+#. module: document_page_approval
+#: field:document.page,approver_gid:0
+msgid "Approver group"
+msgstr "Groupe approbateur"
+
+#. module: document_page_approval
+#: model:ir.model,name:document_page_approval.model_document_page_history
+msgid "Document Page History"
+msgstr "Historique de la page"
+
+#. module: document_page_approval
+#: view:document.page.history:0
+msgid "Approve"
+msgstr "Approuver"
+
+#. module: document_page_approval
+#: selection:document.page.history,state:0
+msgid "Approved"
+msgstr "Approuvée"
+
+#. module: document_page_approval
+#: field:document.page.history,get_approvers_email:0
+msgid "get all approvers email"
+msgstr "Récupérer toutes les adresses courriels des approbateurs"
diff --git a/document_page_approval/images/category.png b/document_page_approval/images/category.png
new file mode 100644
index 00000000..b88e2091
Binary files /dev/null and b/document_page_approval/images/category.png differ
diff --git a/document_page_approval/images/page_history.png b/document_page_approval/images/page_history.png
new file mode 100644
index 00000000..80bee3c3
Binary files /dev/null and b/document_page_approval/images/page_history.png differ
diff --git a/document_page_approval/images/page_history_list.png b/document_page_approval/images/page_history_list.png
new file mode 100644
index 00000000..a2f52232
Binary files /dev/null and b/document_page_approval/images/page_history_list.png differ
diff --git a/document_page_approval/security/document_page_security.xml b/document_page_approval/security/document_page_security.xml
new file mode 100644
index 00000000..7192d3f8
--- /dev/null
+++ b/document_page_approval/security/document_page_security.xml
@@ -0,0 +1,9 @@
+
+
+
+
+ Document approver
+
+
+
+
diff --git a/document_page_approval/security/ir.model.access.csv b/document_page_approval/security/ir.model.access.csv
new file mode 100644
index 00000000..e4835836
--- /dev/null
+++ b/document_page_approval/security/ir.model.access.csv
@@ -0,0 +1,2 @@
+id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
+document_page_history,document.page.history,model_document_page_history,base.group_document_approver_user,1,1,1,0
\ No newline at end of file