120 lines
5.2 KiB
Python
120 lines
5.2 KiB
Python
# -*- coding: utf-8 -*-
|
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.exceptions import UserError
|
|
|
|
|
|
class HrPayslip(models.Model):
|
|
_name = 'hr.payslip'
|
|
_inherit = ['hr.payslip', 'documents.mixin']
|
|
|
|
document_access_url = fields.Char(compute="_compute_document_access_url")
|
|
|
|
def action_resend_payslips(self, notify=False):
|
|
def show_notification(notification_type, message):
|
|
return {
|
|
'type': 'ir.actions.client',
|
|
'tag': 'display_notification',
|
|
'params': {
|
|
'title': _("Send Payslip By Email"),
|
|
'type': notification_type,
|
|
'message': message
|
|
}
|
|
}
|
|
|
|
if not self.env.user.has_group('hr_payroll.group_hr_payroll_user'):
|
|
raise UserError(_('You can not send the documents link to the employee.'))
|
|
payslips_sudo = self.sudo()
|
|
if any(payslip.state not in ['validated', 'paid'] for payslip in payslips_sudo):
|
|
return show_notification('warning', _('A payslip should be validated or paid to be sent to the employee.'))
|
|
invalid_employees = payslips_sudo.employee_id.filtered(lambda e: not (e.private_email or e.work_email))
|
|
if invalid_employees:
|
|
raise UserError(
|
|
_('Employee\'s private or work email must be set to use "Send By Email" function:\n%s',
|
|
'\n'.join(invalid_employees.mapped('name'))))
|
|
|
|
payslip_without_documents = payslips_sudo.filtered(lambda p: not p.document_access_url)
|
|
for payslip in (payslips_sudo - payslip_without_documents):
|
|
template = payslip._get_email_template()
|
|
template.send_mail(payslip.id, email_layout_xmlid='mail.mail_notification_light')
|
|
payslip.message_post(body=_('The payslip has been re-sent to the employee.'))
|
|
|
|
if not notify and not payslip_without_documents: # refresh the form view
|
|
return True
|
|
|
|
message = _("Some payslips could not be resend as they do not have related document") \
|
|
if payslip_without_documents else (
|
|
_("%s Payslip(s) correctly sent.", len(payslips_sudo)))
|
|
notification_type = "warning" if payslip_without_documents else "success"
|
|
return show_notification(notification_type, message)
|
|
|
|
def _get_document_vals_access_rights(self):
|
|
""" All payslips should be accessible in 'Anyone with the link' to make the link permanent.
|
|
The document must be still accessible even if the employee and its user (if any) are archived."""
|
|
return {
|
|
'access_via_link': 'view',
|
|
'access_internal': 'none',
|
|
'is_access_via_link_hidden': True,
|
|
}
|
|
|
|
def _get_document_access_ids(self):
|
|
return [(self._get_document_partner(), ('view', False))]
|
|
|
|
def _get_document_tags(self):
|
|
return self.company_id.documents_hr_payslips_tags
|
|
|
|
def _get_document_partner(self):
|
|
return self.employee_id.user_id.partner_id or self.employee_id.work_contact_id
|
|
|
|
def _get_document_owner(self):
|
|
return self.employee_id.user_id or super()._get_document_owner()
|
|
|
|
def _get_document_folder(self):
|
|
return super()._get_document_folder() if self.employee_id.user_id else self.company_id._get_or_create_worker_payroll_folder()
|
|
|
|
def _check_create_documents(self):
|
|
self.ensure_one()
|
|
return self._get_document_partner().id and (bool(self.employee_id.user_id) or self.company_id.documents_hr_settings)
|
|
|
|
def _get_email_template(self):
|
|
return self.env.ref(
|
|
'documents_hr_payroll.mail_template_new_payslip', raise_if_not_found=False
|
|
)
|
|
|
|
def _compute_document_access_url(self):
|
|
documents = self.env["documents.document"].search(
|
|
[('res_model', '=', self._name), ('res_id', 'in', self.ids)],
|
|
order='res_id, id desc'
|
|
)
|
|
access_url_per_payslip = dict()
|
|
for document in documents:
|
|
if document.res_id not in access_url_per_payslip: # keep last document for each payslip
|
|
access_url_per_payslip[document.res_id] = document.access_url
|
|
for payslip in self:
|
|
payslip.document_access_url = access_url_per_payslip.get(payslip.id)
|
|
|
|
def _check_send_payslip_mail(self):
|
|
self.ensure_one()
|
|
res = super()._check_send_payslip_mail()
|
|
return res and self._check_create_documents()
|
|
|
|
@api.model
|
|
def _cron_generate_pdf(self, batch_size=False):
|
|
is_rescheduled = super()._cron_generate_pdf(batch_size=batch_size)
|
|
if is_rescheduled:
|
|
return is_rescheduled
|
|
|
|
# Post declarations from mixin
|
|
lines = self.env['hr.payroll.employee.declaration'].search([('pdf_to_post', '=', True)])
|
|
if lines:
|
|
BATCH_SIZE = batch_size or 30
|
|
lines_batch = lines[:BATCH_SIZE]
|
|
lines_batch._post_pdf()
|
|
lines_batch.write({'pdf_to_post': False})
|
|
# if necessary, retrigger the cron to generate more pdfs
|
|
if len(lines) > BATCH_SIZE:
|
|
self.env.ref('hr_payroll.ir_cron_generate_payslip_pdfs')._trigger()
|
|
return True
|
|
return False
|