Public release from ruodoo-project: 19.0 - 2026-11-01 22:52:25 UTC

This commit is contained in:
CI Publish Bot
2026-11-01 22:54:30 +00:00
commit 26250aa580
2492 changed files with 664277 additions and 0 deletions

View File

@@ -0,0 +1,4 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import report_payslip_details
from . import report_contribution_register

36
payroll/report/report.xml Normal file
View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="action_contribution_register" model="ir.actions.report">
<field name="name">Payslip Lines</field>
<field name="model">hr.contribution.register</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">payroll.report_contributionregister</field>
<field name="report_file">payroll.report_contributionregister</field>
<field name="print_report_name">PaySlip Lines By Contribution Register</field>
<field name="binding_type">action</field>
</record>
<record id="action_report_payslip" model="ir.actions.report">
<field name="name">Payslip</field>
<field name="model">hr.payslip</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">payroll.report_payslip</field>
<field name="report_file">payroll.report_payslip</field>
<field name="print_report_name">
'Payslip - %s' % (object.employee_id.name)
</field>
<field name="binding_model_id" ref="model_hr_payslip" />
<field name="binding_type">report</field>
</record>
<record id="payslip_details_report" model="ir.actions.report">
<field name="name">PaySlip Details</field>
<field name="model">hr.payslip</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">payroll.report_payslipdetails</field>
<field name="report_file">payroll.report_payslipdetails</field>
<field name="print_report_name">
'Payslip Details - %s' % (object.employee_id.name)
</field>
<field name="binding_model_id" ref="model_hr_payslip" />
<field name="binding_type">report</field>
</record>
</odoo>

View File

@@ -0,0 +1,59 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
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.payroll.report_contributionregister"
_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(
self.env._("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,
}

View File

@@ -0,0 +1,115 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models
class PayslipDetailsReport(models.AbstractModel):
_name = "report.payroll.report_payslipdetails"
_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("line_ids").filtered(lambda r: r.appears_on_payslip)
),
"get_lines_by_contribution_register": self.get_lines_by_contribution_register( # noqa: E501
payslips.mapped("line_ids").filtered(lambda r: r.appears_on_payslip)
),
}