[IMP][10.0][document_page_approval] Change Requests and workflow improvements on documents (#155)

This commit is contained in:
Iván Todorovich
2018-04-13 11:38:18 -03:00
committed by Laurence Lars Labusch
parent a22bc6d58b
commit 9426f2823c
85 changed files with 17123 additions and 693 deletions

View File

@@ -2,7 +2,9 @@
# Copyright (C) 2013 Savoir-faire Linux (<http://www.savoirfairelinux.com>).
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp import api, fields, models
from odoo import api, fields, models
from ast import literal_eval
class DocumentPageApproval(models.Model):
@@ -10,104 +12,126 @@ class DocumentPageApproval(models.Model):
_inherit = 'document.page'
@api.multi
def _get_display_content(self):
"""Display the content of document."""
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
@api.multi
def _get_approved_date(self):
"""Return the approved date of a document."""
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
@api.multi
def _get_approved_uid(self):
"""Return the user's id of the approved user."""
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
@api.multi
def _is_parent_approval_required(self):
"""Check if the document requires approval base on his parent."""
for page in self:
page.is_parent_approval_required = self.is_approval_required(page)
def is_approval_required(self, page):
"""Check if a document requires approval."""
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'
history_ids = fields.One2many(
order='approved_date DESC',
domain=[('state', '=', 'approved')],
)
approved_date = fields.Datetime(
compute=_get_approved_date,
string="Approved Date"
'Approved Date',
related='history_head.approved_date',
store=True,
index=True,
readonly=True,
)
approved_uid = fields.Many2one(
'res.users',
compute=_get_approved_uid,
string="Approved By",
'Approved by',
related='history_head.approved_uid',
store=True,
index=True,
readonly=True,
)
approval_required = fields.Boolean("Require approval")
is_parent_approval_required = fields.Boolean(
compute=_is_parent_approval_required,
string="parent approval"
approval_required = fields.Boolean(
'Require approval',
help='Require approval for changes on this page or its child pages.',
)
approver_gid = fields.Many2one(
"res.groups",
"Approver group"
"Approver group",
help='Users must also belong to the Approvers group',
)
is_approval_required = fields.Boolean(
'Approval required',
help='If true, changes of this page require approval',
compute='_compute_is_approval_required',
)
am_i_approver = fields.Boolean(
compute='_compute_am_i_approver'
)
approver_group_ids = fields.Many2many(
'res.groups',
string='Approver groups',
help='Groups that can approve changes to this document',
compute='_compute_approver_group_ids',
)
has_changes_pending_approval = fields.Boolean(
compute='_compute_has_changes_pending_approval',
string='Has changes pending approval'
)
@api.multi
@api.depends('approval_required', 'parent_id.is_approval_required')
def _compute_is_approval_required(self):
"""Check if the document required approval based on his parents."""
for page in self:
res = page.approval_required
if page.parent_id:
res = res or page.parent_id.is_approval_required
page.is_approval_required = res
@api.multi
@api.depends('approver_gid', 'parent_id.approver_group_ids')
def _compute_approver_group_ids(self):
"""Compute the approver groups based on his parents."""
for page in self:
res = page.approver_gid
if page.parent_id:
res = res | page.parent_id.approver_group_ids
page.approver_group_ids = res
@api.multi
@api.depends('is_approval_required', 'approver_group_ids')
def _compute_am_i_approver(self):
"""Check if the current user can approve changes to this page."""
for rec in self:
rec.am_i_approver = rec.can_user_approve_this_page(self.env.user)
@api.multi
def can_user_approve_this_page(self, user):
"""Check if a user can approve this page."""
self.ensure_one()
# if it's not required, anyone can approve
if not self.is_approval_required:
return True
# to approve, you must have approver rights
approver_group_id = self.env.ref(
'document_page_approval.group_document_approver_user')
if approver_group_id not in user.groups_id:
return False
# and belong to at least one of the approver_groups (if any is set)
if not self.approver_group_ids:
return True
return len(user.groups_id & self.approver_group_ids) > 0
@api.multi
def _compute_has_changes_pending_approval(self):
history = self.env['document.page.history']
for rec in self:
changes = history.search_count([
('page_id', '=', rec.id),
('state', '=', 'to approve')])
rec.has_changes_pending_approval = (changes > 0)
@api.multi
def _create_history(self, vals):
res = super(DocumentPageApproval, self)._create_history(vals)
res.signal_workflow('document_page_auto_confirm')
@api.multi
def action_changes_pending_approval(self):
self.ensure_one()
action = self.env.ref('document_page_approval.action_change_requests')
action = action.read()[0]
context = literal_eval(action['context'])
context['search_default_page_id'] = self.id
context['default_page_id'] = self.id
action['context'] = context
return action

View File

@@ -11,117 +11,122 @@ from odoo import api, fields, models
class DocumentPageHistoryWorkflow(models.Model):
"""Useful to manage edition's workflow on a document."""
_inherit = 'document.page.history'
_name = 'document.page.history'
_inherit = ['document.page.history', 'mail.thread']
state = fields.Selection([
('draft', 'Draft'),
('to approve', 'Pending Approval'),
('approved', 'Approved'),
('cancelled', 'Cancelled')],
'Status',
readonly=True,
)
approved_date = fields.Datetime(
'Approved Date',
)
approved_uid = fields.Many2one(
'res.users',
'Approved by',
)
is_approval_required = fields.Boolean(
related='page_id.is_approval_required',
string="Approval required",
)
am_i_owner = fields.Boolean(
compute='_compute_am_i_owner'
)
am_i_approver = fields.Boolean(
related='page_id.am_i_approver'
)
page_url = fields.Text(
compute='_compute_page_url',
string="URL",
)
@api.multi
def page_approval_draft(self):
"""Set a document state as draft and notified the reviewers."""
"""Set a change request as draft"""
self.write({'state': 'draft'})
@api.multi
def page_approval_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')
for page in self:
if page.is_parent_approval_required:
template.send_mail(page.id, force_send=True)
return True
approver_gid = self.env.ref(
'document_page_approval.group_document_approver_user')
for rec in self:
if rec.is_approval_required:
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)
@api.multi
def page_approval_approved(self):
"""Set a document state as approve."""
message_obj = self.env['mail.message']
"""Set a change request as approved."""
self.write({
'state': 'approved',
'approved_date': datetime.now().strftime(
DEFAULT_SERVER_DATETIME_FORMAT),
'approved_uid': self.env.uid
})
# Notify followers a new version is available
for page_history in self:
subtype = self.env.ref('mail.mt_comment')
message_obj.create(
{'res_id': page_history.page_id.id,
'model': 'document.page',
'subtype_id': subtype.id,
'body': _('New version of the document %s'
' approved.') % page_history.page_id.name
}
for rec in self:
# Trigger computed field update
rec.page_id._compute_history_head()
# Notify state change
rec.message_post(
subtype='mt_comment',
body=_(
'Change request has been approved by %s.'
) % (self.env.user.name)
)
return True
@api.multi
def _can_user_approve_page(self):
"""Check if a user cas approve the page."""
user = self.env.user
for page in self:
page.can_user_approve_page = page.can_user_approve_this_page(
page.page_id,
user
# Notify followers a new version is available
rec.page_id.message_post(
subtype='mt_comment',
body=_(
'New version of the document %s approved.'
) % (rec.page_id.name)
)
def can_user_approve_this_page(self, page, user):
"""Check if a user can approved the page."""
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
@api.multi
def page_approval_cancelled(self):
"""Set a change request as cancelled."""
self.write({'state': 'cancelled'})
for rec in self:
rec.message_post(
subtype='mt_comment',
body=_(
'Change request <b>%s</b> has been cancelled by %s.'
) % (rec.display_name, self.env.user.name)
)
@api.multi
def get_approvers_guids(self):
"""Return the approvers group."""
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):
"""Return the approvers group for a 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 _compute_am_i_owner(self):
"""Check if current user is the owner"""
for rec in self:
rec.am_i_owner = (rec.create_uid == self.env.user)
@api.multi
def _get_approvers_email(self):
"""Get the approvers email."""
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]
@api.multi
def _get_page_url(self):
"""Get the page url."""
def _compute_page_url(self):
"""Compute the page url."""
for page in self:
base_url = self.env['ir.config_parameter'].get_param(
'web.base.url',
default='http://localhost:8069'
)
page.get_page_url = (
page.page_url = (
'{}/web#db={}&id={}&view_type=form&'
'model=document.page.history').format(
base_url,
@@ -129,37 +134,18 @@ class DocumentPageHistoryWorkflow(models.Model):
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
)
@api.multi
def _compute_diff(self):
"""Shows a diff between this version and the previous version"""
history = self.env['document.page.history']
for rec in self:
domain = [
('page_id', '=', rec.page_id.id),
('state', '=', 'approved')]
if rec.approved_date:
domain.append(('approved_date', '<', rec.approved_date))
prev = history.search(domain, limit=1, order='approved_date DESC')
if prev:
rec.diff = self.getDiff(prev.id, rec.id)
else:
rec.diff = self.getDiff(False, rec.id)