From bbffafdae62cba9385f1d6a1c949a000f7b94a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Fri, 20 Apr 2018 10:42:49 -0300 Subject: [PATCH 01/10] [document_page_approval] Rename classes and files to match model names, and removed workflow engine. --- document_page_approval/__manifest__.py | 1 - document_page_approval/models/__init__.py | 2 +- ...ment_page_approval.py => document_page.py} | 6 +- ...y_workflow.py => document_page_history.py} | 60 +++++++--- .../tests/test_document_page_approval.py | 14 +-- .../views/document_page_approval.xml | 10 +- .../workflows/document_page_approval.xml | 104 ------------------ 7 files changed, 61 insertions(+), 136 deletions(-) rename document_page_approval/models/{document_page_approval.py => document_page.py} (96%) rename document_page_approval/models/{document_page_history_workflow.py => document_page_history.py} (68%) delete mode 100644 document_page_approval/workflows/document_page_approval.xml diff --git a/document_page_approval/__manifest__.py b/document_page_approval/__manifest__.py index a2403bbb4e2..6c2a4a8bb8d 100644 --- a/document_page_approval/__manifest__.py +++ b/document_page_approval/__manifest__.py @@ -15,7 +15,6 @@ ], 'data': [ 'data/email_template.xml', - 'workflows/document_page_approval.xml', 'views/document_page_approval.xml', 'security/document_page_security.xml', 'security/ir.model.access.csv', diff --git a/document_page_approval/models/__init__.py b/document_page_approval/models/__init__.py index 91075fe8bcc..895435cf6b7 100644 --- a/document_page_approval/models/__init__.py +++ b/document_page_approval/models/__init__.py @@ -1,2 +1,2 @@ # -*- coding: utf-8 -*- -from . import document_page_approval, document_page_history_workflow +from . import document_page, document_page_history diff --git a/document_page_approval/models/document_page_approval.py b/document_page_approval/models/document_page.py similarity index 96% rename from document_page_approval/models/document_page_approval.py rename to document_page_approval/models/document_page.py index 5ff46dfefed..779853dd847 100644 --- a/document_page_approval/models/document_page_approval.py +++ b/document_page_approval/models/document_page.py @@ -7,7 +7,7 @@ from ast import literal_eval -class DocumentPageApproval(models.Model): +class DocumentPage(models.Model): """Useful to know the state of a document.""" _inherit = 'document.page' @@ -122,8 +122,8 @@ def _compute_has_changes_pending_approval(self): @api.multi def _create_history(self, vals): - res = super(DocumentPageApproval, self)._create_history(vals) - res.signal_workflow('document_page_auto_confirm') + res = super(DocumentPage, self)._create_history(vals) + res.action_to_approve() @api.multi def action_changes_pending_approval(self): diff --git a/document_page_approval/models/document_page_history_workflow.py b/document_page_approval/models/document_page_history.py similarity index 68% rename from document_page_approval/models/document_page_history_workflow.py rename to document_page_approval/models/document_page_history.py index a745ea58ec9..8d9f857f356 100644 --- a/document_page_approval/models/document_page_history_workflow.py +++ b/document_page_approval/models/document_page_history.py @@ -2,13 +2,12 @@ # Copyright (C) 2013 Savoir-faire Linux (). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from datetime import datetime from odoo.tools.translate import _ -from odoo.tools import DEFAULT_SERVER_DATETIME_FORMAT from odoo import api, fields, models +from odoo.exceptions import UserError -class DocumentPageHistoryWorkflow(models.Model): +class DocumentPageHistory(models.Model): """Useful to manage edition's workflow on a document.""" _name = 'document.page.history' @@ -20,6 +19,7 @@ class DocumentPageHistoryWorkflow(models.Model): ('approved', 'Approved'), ('cancelled', 'Cancelled')], 'Status', + default='draft', readonly=True, ) @@ -51,37 +51,67 @@ class DocumentPageHistoryWorkflow(models.Model): ) @api.multi - def page_approval_draft(self): + def action_draft(self): """Set a change request as draft""" - self.write({'state': 'draft'}) + for rec in self: + if not rec.state == 'cancelled': + raise UserError( + _('You need to cancel it before reopening.')) + if not (rec.am_i_owner or rec.am_i_approver): + raise UserError( + _('You are not authorized to do this.\r\n' + 'Only owners or approvers can reopen Change Requests.')) + rec.write({'state': 'draft'}) @api.multi - def page_approval_to_approve(self): + def action_to_approve(self): """Set a change request as to approve""" - self.write({'state': 'to approve'}) template = self.env.ref( 'document_page_approval.email_template_new_draft_need_approval') approver_gid = self.env.ref( 'document_page_approval.group_document_approver_user') for rec in self: + if rec.state != 'draft': + raise UserError( + _("Can't approve pages in '%s' state.") % rec.state) + if not (rec.am_i_owner or rec.am_i_approver): + raise UserError( + _('You are not authorized to do this.\r\n' + 'Only owners or approvers can request approval.')) + # request approval if rec.is_approval_required: + rec.write({'state': 'to approve'}) guids = [g.id for g in rec.page_id.approver_group_ids] users = self.env['res.users'].search([ ('groups_id', 'in', guids), ('groups_id', 'in', approver_gid.id)]) rec.message_subscribe_users([u.id for u in users]) rec.message_post_with_template(template.id) + else: + # auto-approve if approval is not required + rec.action_approve() @api.multi - def page_approval_approved(self): + def action_approve(self): """Set a change request as approved.""" - self.write({ - 'state': 'approved', - 'approved_date': datetime.now().strftime( - DEFAULT_SERVER_DATETIME_FORMAT), - 'approved_uid': self.env.uid - }) for rec in self: + if rec.state not in ['draft', 'to approve']: + raise UserError( + _("Can't approve page in '%s' state.") % rec.state) + if not rec.am_i_approver: + raise UserError(_( + 'You are not authorized to do this.\r\n' + 'Only approvers with these groups can approve this: ' + ) % ', '.join( + [g.display_name + for g in rec.page_id.approver_group_ids]) + ) + # Update state + rec.write({ + 'state': 'approved', + 'approved_date': fields.datetime.now(), + 'approved_uid': self.env.uid, + }) # Trigger computed field update rec.page_id._compute_history_head() # Notify state change @@ -100,7 +130,7 @@ def page_approval_approved(self): ) @api.multi - def page_approval_cancelled(self): + def action_cancel(self): """Set a change request as cancelled.""" self.write({'state': 'cancelled'}) for rec in self: diff --git a/document_page_approval/tests/test_document_page_approval.py b/document_page_approval/tests/test_document_page_approval.py index 5e4f89b58bc..de97ff756bc 100644 --- a/document_page_approval/tests/test_document_page_approval.py +++ b/document_page_approval/tests/test_document_page_approval.py @@ -48,7 +48,7 @@ def test_change_request_approve(self): self.assertTrue(chreq.am_i_approver) # approve - chreq.signal_workflow('page_approval_approve') + chreq.action_approve() self.assertEqual(chreq.state, 'approved') self.assertEqual(chreq.content, page.content) @@ -59,7 +59,7 @@ def test_change_request_approve(self): ('page_id', '=', page.id), ('state', '!=', 'approved') ])[0] - chreq.signal_workflow('page_approval_approve') + chreq.action_approve() self.assertEqual(page.content, 'New content') def test_change_request_auto_approve(self): @@ -75,7 +75,7 @@ def test_change_request_from_scratch(self): self.history_obj.search([ ('page_id', '=', page.id), ('state', '!=', 'approved') - ]).signal_workflow('page_approval_approve') + ]).action_approve() # new change request from scrath chreq = self.history_obj.create({ @@ -89,25 +89,25 @@ def test_change_request_from_scratch(self): self.assertNotEqual(page.approved_date, chreq.approved_date) self.assertNotEqual(page.approved_uid, chreq.approved_uid) - chreq.signal_workflow('page_approval_to_approve') + chreq.action_to_approve() self.assertEqual(chreq.state, 'to approve') self.assertNotEqual(page.content, chreq.content) self.assertNotEqual(page.approved_date, chreq.approved_date) self.assertNotEqual(page.approved_uid, chreq.approved_uid) - chreq.signal_workflow('page_approval_cancel') + chreq.action_cancel() self.assertEqual(chreq.state, 'cancelled') self.assertNotEqual(page.content, chreq.content) self.assertNotEqual(page.approved_date, chreq.approved_date) self.assertNotEqual(page.approved_uid, chreq.approved_uid) - chreq.signal_workflow('page_approval_reopen') + chreq.action_draft() self.assertEqual(chreq.state, 'draft') self.assertNotEqual(page.content, chreq.content) self.assertNotEqual(page.approved_date, chreq.approved_date) self.assertNotEqual(page.approved_uid, chreq.approved_uid) - chreq.signal_workflow('page_approval_approve') + chreq.action_approve() self.assertEqual(chreq.state, 'approved') self.assertEqual(page.content, chreq.content) self.assertEqual(page.approved_date, chreq.approved_date) diff --git a/document_page_approval/views/document_page_approval.xml b/document_page_approval/views/document_page_approval.xml index f6ff140d43a..825a0cb72ba 100644 --- a/document_page_approval/views/document_page_approval.xml +++ b/document_page_approval/views/document_page_approval.xml @@ -10,19 +10,19 @@
- From 63e1a65d7d2dafd9251af5499fd4fe6cd0fc1cdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Tue, 24 Apr 2018 15:37:38 -0300 Subject: [PATCH 06/10] [document_page_approval] Update version number --- document_page_approval/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/document_page_approval/__manifest__.py b/document_page_approval/__manifest__.py index 6c2a4a8bb8d..1e5c3de2b95 100644 --- a/document_page_approval/__manifest__.py +++ b/document_page_approval/__manifest__.py @@ -4,7 +4,7 @@ { 'name': 'Document Page Approval', - 'version': '10.0.2.0.0', + 'version': '10.0.2.1.0', "author": "Savoir-faire Linux, Odoo Community Association (OCA)", "website": "http://www.savoirfairelinux.com", "license": "AGPL-3", From 1c03364ffdb24ba24ad9837bd81da9e9b3f5eac5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Tue, 24 Apr 2018 15:50:18 -0300 Subject: [PATCH 07/10] [document_page_approval] Fix LINT --- document_page_approval/models/document_page_history.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/document_page_approval/models/document_page_history.py b/document_page_approval/models/document_page_history.py index 8d9f857f356..9b95a7ea2e2 100644 --- a/document_page_approval/models/document_page_history.py +++ b/document_page_approval/models/document_page_history.py @@ -103,9 +103,8 @@ def action_approve(self): 'You are not authorized to do this.\r\n' 'Only approvers with these groups can approve this: ' ) % ', '.join( - [g.display_name - for g in rec.page_id.approver_group_ids]) - ) + [g.display_name + for g in rec.page_id.approver_group_ids])) # Update state rec.write({ 'state': 'approved', From d0f6405e3b64f849492adc1e8c819e94559fcb3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Tue, 24 Apr 2018 19:57:09 -0300 Subject: [PATCH 08/10] [document_page_approval] Add ir.rules for document.page.history --- .../security/document_page_security.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/document_page_approval/security/document_page_security.xml b/document_page_approval/security/document_page_security.xml index ab80c13fad9..ab79d1ef565 100644 --- a/document_page_approval/security/document_page_security.xml +++ b/document_page_approval/security/document_page_security.xml @@ -11,4 +11,25 @@ + + Change Request Global + + ['|',('state','=','approved'),('create_uid','=',user.id)] + + + + + + + + Change Request Approver + + + [('state','!=','draft')] + + + + + + From 4f76b1a19f8c76e751077db292fe25c07ad712f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Iv=C3=A1n=20Todorovich?= Date: Tue, 24 Apr 2018 20:07:07 -0300 Subject: [PATCH 09/10] [document_page_approval] Allow to quickly cancel&draft from 'to approve' state --- document_page_approval/models/document_page_history.py | 6 ++++++ document_page_approval/views/document_page_approval.xml | 3 +++ 2 files changed, 9 insertions(+) diff --git a/document_page_approval/models/document_page_history.py b/document_page_approval/models/document_page_history.py index 9b95a7ea2e2..ed74e00ccca 100644 --- a/document_page_approval/models/document_page_history.py +++ b/document_page_approval/models/document_page_history.py @@ -140,6 +140,12 @@ def action_cancel(self): ) % (rec.display_name, self.env.user.name) ) + @api.multi + def action_cancel_and_draft(self): + """Set a change request as draft, cancelling it first""" + self.action_cancel() + self.action_draft() + @api.multi def _compute_am_i_owner(self): """Check if current user is the owner""" diff --git a/document_page_approval/views/document_page_approval.xml b/document_page_approval/views/document_page_approval.xml index 2ae3b0f137c..5f7759c6172 100644 --- a/document_page_approval/views/document_page_approval.xml +++ b/document_page_approval/views/document_page_approval.xml @@ -24,6 +24,9 @@