196 lines
6.2 KiB
Python
196 lines
6.2 KiB
Python
|
|
# -*- coding: utf-8 -*-
|
||
|
|
from odoo import api, fields, models, _
|
||
|
|
from odoo.exceptions import ValidationError
|
||
|
|
from .selection import ApproverState, ApprovalMethods, ApprovalStep
|
||
|
|
|
||
|
|
|
||
|
|
class DocApprovalTeam(models.Model):
|
||
|
|
_name = 'xf.doc.approval.team'
|
||
|
|
_description = 'Doc Approval Team'
|
||
|
|
|
||
|
|
active = fields.Boolean('Active', default=True)
|
||
|
|
|
||
|
|
name = fields.Char(
|
||
|
|
string='Name',
|
||
|
|
required=True,
|
||
|
|
)
|
||
|
|
user_id = fields.Many2one(
|
||
|
|
string='Team Leader',
|
||
|
|
comodel_name='res.users',
|
||
|
|
required=True,
|
||
|
|
default=lambda self: self.env.user,
|
||
|
|
index=True
|
||
|
|
)
|
||
|
|
company_id = fields.Many2one(
|
||
|
|
string='Company',
|
||
|
|
comodel_name='res.company',
|
||
|
|
required=True,
|
||
|
|
default=lambda self: self.env.company.id,
|
||
|
|
index=True,
|
||
|
|
)
|
||
|
|
approver_ids = fields.One2many(
|
||
|
|
string='Approvers',
|
||
|
|
comodel_name='xf.doc.approval.team.approver',
|
||
|
|
inverse_name='team_id',
|
||
|
|
)
|
||
|
|
|
||
|
|
# Validation
|
||
|
|
|
||
|
|
@api.constrains('company_id')
|
||
|
|
def _check_team_company(self):
|
||
|
|
for team in self:
|
||
|
|
team.approver_ids.validate_company(team.company_id)
|
||
|
|
|
||
|
|
|
||
|
|
class DocApprovalApproverAbstract(models.Model):
|
||
|
|
_name = 'xf.doc.approval.approver.abstract'
|
||
|
|
_description = 'Abstract Approver'
|
||
|
|
_order = 'step'
|
||
|
|
_rec_name = 'user_id'
|
||
|
|
step = fields.Selection(
|
||
|
|
string='Step',
|
||
|
|
selection=ApprovalStep.list,
|
||
|
|
required=True,
|
||
|
|
default=ApprovalStep.default,
|
||
|
|
)
|
||
|
|
user_id = fields.Many2one(
|
||
|
|
string='Approver',
|
||
|
|
comodel_name='res.users',
|
||
|
|
required=True
|
||
|
|
)
|
||
|
|
role = fields.Char(
|
||
|
|
string='Role/Position',
|
||
|
|
required=True,
|
||
|
|
default="Approver"
|
||
|
|
)
|
||
|
|
|
||
|
|
# Onchange handlers
|
||
|
|
|
||
|
|
@api.onchange('user_id')
|
||
|
|
def _detect_user_role(self):
|
||
|
|
for approver in self:
|
||
|
|
# if user related to employee, try to get job title for hr.employee
|
||
|
|
employee = hasattr(approver.user_id, 'employee_ids') and getattr(approver.user_id, 'employee_ids')
|
||
|
|
employee_job_id = hasattr(employee, 'job_id') and getattr(employee, 'job_id')
|
||
|
|
employee_job_title = employee_job_id.name if employee_job_id else False
|
||
|
|
if employee_job_title:
|
||
|
|
approver.role = employee_job_title
|
||
|
|
continue
|
||
|
|
# if user related partner, try to get job title for res.partner
|
||
|
|
partner = approver.user_id.partner_id
|
||
|
|
partner_job_title = hasattr(partner, 'function') and getattr(partner, 'function')
|
||
|
|
if partner_job_title:
|
||
|
|
approver.role = partner_job_title
|
||
|
|
|
||
|
|
# Validation
|
||
|
|
|
||
|
|
@api.constrains('user_id')
|
||
|
|
def _check_users(self):
|
||
|
|
for approver in self:
|
||
|
|
if not approver.user_id.has_group('xf_doc_approval.group_xf_doc_approval_user'):
|
||
|
|
raise ValidationError(_('%s does not have access to the Doc Approval module.') % (approver.user_id.name,)
|
||
|
|
+ '\n' +
|
||
|
|
_('Please ask system administrator to add him/her to the Doc Approval module group first.'))
|
||
|
|
|
||
|
|
def validate_company(self, company):
|
||
|
|
if not company:
|
||
|
|
return
|
||
|
|
for approver in self:
|
||
|
|
if company not in approver.user_id.company_ids:
|
||
|
|
raise ValidationError(
|
||
|
|
_('%s does not have access to the company %s') % (approver.user_id.name, company.name))
|
||
|
|
|
||
|
|
|
||
|
|
class DocApprovalTeamApprover(models.Model):
|
||
|
|
_name = 'xf.doc.approval.team.approver'
|
||
|
|
_inherit = ['xf.doc.approval.approver.abstract']
|
||
|
|
_description = 'Approval Team Member'
|
||
|
|
|
||
|
|
team_id = fields.Many2one(
|
||
|
|
string='Team',
|
||
|
|
comodel_name='xf.doc.approval.team',
|
||
|
|
required=True,
|
||
|
|
ondelete='cascade'
|
||
|
|
)
|
||
|
|
|
||
|
|
# Validation
|
||
|
|
|
||
|
|
@api.constrains('user_id', 'team_id')
|
||
|
|
def _check_users(self):
|
||
|
|
for approver in self:
|
||
|
|
approver.validate_company(approver.team_id.company_id)
|
||
|
|
return super(DocApprovalTeamApprover, self)._check_users()
|
||
|
|
|
||
|
|
|
||
|
|
class DocApprovalDocumentApprover(models.Model):
|
||
|
|
_name = 'xf.doc.approval.document.approver'
|
||
|
|
_inherit = ['xf.doc.approval.approver.abstract']
|
||
|
|
_description = 'Doc Approver'
|
||
|
|
|
||
|
|
team_approver_id = fields.Many2one(
|
||
|
|
string='Doc Team Approver',
|
||
|
|
comodel_name='xf.doc.approval.team.approver',
|
||
|
|
ondelete='set null'
|
||
|
|
)
|
||
|
|
document_package_id = fields.Many2one(
|
||
|
|
string='Document Package',
|
||
|
|
comodel_name='xf.doc.approval.document.package',
|
||
|
|
required=True,
|
||
|
|
ondelete='cascade',
|
||
|
|
)
|
||
|
|
method = fields.Selection(
|
||
|
|
string='Method',
|
||
|
|
related='document_package_id.method',
|
||
|
|
readonly=True,
|
||
|
|
)
|
||
|
|
state = fields.Selection(
|
||
|
|
string='Status',
|
||
|
|
selection=ApproverState.list,
|
||
|
|
readonly=True,
|
||
|
|
required=True,
|
||
|
|
default=ApproverState.default
|
||
|
|
)
|
||
|
|
notes = fields.Text(
|
||
|
|
string='Notes',
|
||
|
|
readonly=True,
|
||
|
|
)
|
||
|
|
|
||
|
|
# Validation
|
||
|
|
|
||
|
|
@api.constrains('user_id', 'document_package_id')
|
||
|
|
def _check_users(self):
|
||
|
|
for approver in self:
|
||
|
|
approver.validate_company(approver.document_package_id.company_id)
|
||
|
|
return super(DocApprovalDocumentApprover, self)._check_users()
|
||
|
|
|
||
|
|
# User actions
|
||
|
|
|
||
|
|
def action_wizard(self, view_ref, window_title):
|
||
|
|
self.ensure_one()
|
||
|
|
view = self.env.ref('xf_doc_approval.' + view_ref)
|
||
|
|
return {
|
||
|
|
'name': window_title,
|
||
|
|
'type': 'ir.actions.act_window',
|
||
|
|
'view_type': 'form',
|
||
|
|
'view_mode': 'form',
|
||
|
|
'res_model': self._name,
|
||
|
|
'res_id': self.id,
|
||
|
|
'views': [(view.id, 'form')],
|
||
|
|
'view_id': view.id,
|
||
|
|
'target': 'new'
|
||
|
|
}
|
||
|
|
|
||
|
|
def action_approve(self):
|
||
|
|
for approver in self:
|
||
|
|
document_package = approver.document_package_id
|
||
|
|
approver.state = 'approved'
|
||
|
|
if document_package.approval_state == 'to approve':
|
||
|
|
document_package.sudo().action_send_for_approval()
|
||
|
|
elif document_package.approval_state == 'approved':
|
||
|
|
document_package.sudo().action_finish_approval()
|
||
|
|
|
||
|
|
def action_reject(self):
|
||
|
|
for approver in self:
|
||
|
|
approver.state = 'rejected'
|
||
|
|
approver.document_package_id.sudo().set_state('rejected', {'reject_reason': approver.notes})
|