diff options
Diffstat (limited to 'om_hr_payroll/report')
| -rw-r--r-- | om_hr_payroll/report/__init__.py | 4 | ||||
| -rw-r--r-- | om_hr_payroll/report/report_contribution_register.py | 52 | ||||
| -rw-r--r-- | om_hr_payroll/report/report_payslip_details.py | 99 |
3 files changed, 155 insertions, 0 deletions
diff --git a/om_hr_payroll/report/__init__.py b/om_hr_payroll/report/__init__.py new file mode 100644 index 0000000..a5895bb --- /dev/null +++ b/om_hr_payroll/report/__init__.py @@ -0,0 +1,4 @@ +# -*- coding:utf-8 -*- + +from . import report_payslip_details +from . import report_contribution_register diff --git a/om_hr_payroll/report/report_contribution_register.py b/om_hr_payroll/report/report_contribution_register.py new file mode 100644 index 0000000..7b6fad4 --- /dev/null +++ b/om_hr_payroll/report/report_contribution_register.py @@ -0,0 +1,52 @@ +# -*- coding:utf-8 -*- + + +from datetime import datetime +from dateutil.relativedelta import relativedelta + +from odoo import api, fields, models, _ +from odoo.exceptions import UserError + + +class ContributionRegisterReport(models.AbstractModel): + _name = 'report.om_om_hr_payroll.report_contribution_register' + _description = 'Payroll Contribution Register Report' + + def _get_payslip_lines(self, register_ids, date_from, date_to): + result = {} + self.env.cr.execute(""" + SELECT pl.id from hr_payslip_line as pl + LEFT JOIN hr_payslip AS hp on (pl.slip_id = hp.id) + WHERE (hp.date_from >= %s) AND (hp.date_to <= %s) + AND pl.register_id in %s + AND hp.state = 'done' + ORDER BY pl.slip_id, pl.sequence""", + (date_from, date_to, tuple(register_ids))) + line_ids = [x[0] for x in self.env.cr.fetchall()] + for line in self.env['hr.payslip.line'].browse(line_ids): + result.setdefault(line.register_id.id, self.env['hr.payslip.line']) + result[line.register_id.id] += line + return result + + @api.model + def _get_report_values(self, docids, data=None): + if not data.get('form'): + raise UserError(_("Form content is missing, this report cannot be printed.")) + + register_ids = self.env.context.get('active_ids', []) + contrib_registers = self.env['hr.contribution.register'].browse(register_ids) + date_from = data['form'].get('date_from', fields.Date.today()) + date_to = data['form'].get('date_to', str(datetime.now() + relativedelta(months=+1, day=1, days=-1))[:10]) + lines_data = self._get_payslip_lines(register_ids, date_from, date_to) + lines_total = {} + for register in contrib_registers: + lines = lines_data.get(register.id) + lines_total[register.id] = lines and sum(lines.mapped('total')) or 0.0 + return { + 'doc_ids': register_ids, + 'doc_model': 'hr.contribution.register', + 'docs': contrib_registers, + 'data': data, + 'lines_data': lines_data, + 'lines_total': lines_total + } diff --git a/om_hr_payroll/report/report_payslip_details.py b/om_hr_payroll/report/report_payslip_details.py new file mode 100644 index 0000000..52a519e --- /dev/null +++ b/om_hr_payroll/report/report_payslip_details.py @@ -0,0 +1,99 @@ +# -*- coding:utf-8 -*- + +from odoo import api, models + + +class PayslipDetailsReport(models.AbstractModel): + _name = 'report.om_hr_payroll.report_payslip_details' + _description = 'Payslip Details Report' + + def get_details_by_rule_category(self, payslip_lines): + PayslipLine = self.env['hr.payslip.line'] + RuleCateg = self.env['hr.salary.rule.category'] + + def get_recursive_parent(current_rule_category, rule_categories=None): + if rule_categories: + rule_categories = current_rule_category | rule_categories + else: + rule_categories = current_rule_category + + if current_rule_category.parent_id: + return get_recursive_parent(current_rule_category.parent_id, rule_categories) + else: + return rule_categories + + res = {} + result = {} + + if payslip_lines: + self.env.cr.execute(""" + SELECT pl.id, pl.category_id, pl.slip_id FROM hr_payslip_line as pl + LEFT JOIN hr_salary_rule_category AS rc on (pl.category_id = rc.id) + WHERE pl.id in %s + GROUP BY rc.parent_id, pl.sequence, pl.id, pl.category_id + ORDER BY pl.sequence, rc.parent_id""", + (tuple(payslip_lines.ids),)) + for x in self.env.cr.fetchall(): + result.setdefault(x[2], {}) + result[x[2]].setdefault(x[1], []) + result[x[2]][x[1]].append(x[0]) + for payslip_id, lines_dict in result.items(): + res.setdefault(payslip_id, []) + for rule_categ_id, line_ids in lines_dict.items(): + rule_categories = RuleCateg.browse(rule_categ_id) + lines = PayslipLine.browse(line_ids) + level = 0 + for parent in get_recursive_parent(rule_categories): + res[payslip_id].append({ + 'rule_category': parent.name, + 'name': parent.name, + 'code': parent.code, + 'level': level, + 'total': sum(lines.mapped('total')), + }) + level += 1 + for line in lines: + res[payslip_id].append({ + 'rule_category': line.name, + 'name': line.name, + 'code': line.code, + 'total': line.total, + 'level': level + }) + return res + + def get_lines_by_contribution_register(self, payslip_lines): + result = {} + res = {} + for line in payslip_lines.filtered('register_id'): + result.setdefault(line.slip_id.id, {}) + result[line.slip_id.id].setdefault(line.register_id, line) + result[line.slip_id.id][line.register_id] |= line + for payslip_id, lines_dict in result.items(): + res.setdefault(payslip_id, []) + for register, lines in lines_dict.items(): + res[payslip_id].append({ + 'register_name': register.name, + 'total': sum(lines.mapped('total')), + }) + for line in lines: + res[payslip_id].append({ + 'name': line.name, + 'code': line.code, + 'quantity': line.quantity, + 'amount': line.amount, + 'total': line.total, + }) + return res + + @api.model + def _get_report_values(self, docids, data=None): + payslips = self.env['hr.payslip'].browse(docids) + return { + 'doc_ids': docids, + 'doc_model': 'hr.payslip', + 'docs': payslips, + 'data': data, + 'get_details_by_rule_category': self.get_details_by_rule_category(payslips.mapped('details_by_salary_rule_category').filtered(lambda r: r.appears_on_payslip)), + 'get_lines_by_contribution_register': self.get_lines_by_contribution_register(payslips.mapped('line_ids').filtered(lambda r: r.appears_on_payslip)), + } |
