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