[IMP] hr_payroll: Remove 'Details By Salary Rules Category'
This field brings nothing more than the payslip lines. Btw the term is badly chosen, it doesn't display the lines by salary rules category, it displays the payslip lines that have a category. The printed report is not very useful too. The only interesting part is the contribution register at the end of the report, and there is already a dedicated report for that.
This commit is contained in:
@@ -27,7 +27,6 @@
|
||||
'views/res_config_settings_views.xml',
|
||||
'views/report_contributionregister_templates.xml',
|
||||
'views/report_payslip_templates.xml',
|
||||
'views/report_payslipdetails_templates.xml',
|
||||
'views/hr_benefit_views.xml',
|
||||
'views/hr_benefit_views.xml',
|
||||
'views/hr_leave_views.xml',
|
||||
|
||||
@@ -59,8 +59,6 @@ class HrPayslip(models.Model):
|
||||
note = fields.Text(string='Internal Note', readonly=True, states={'draft': [('readonly', False)]})
|
||||
contract_id = fields.Many2one('hr.contract', string='Contract', readonly=True,
|
||||
states={'draft': [('readonly', False)]})
|
||||
details_by_salary_rule_category = fields.One2many('hr.payslip.line',
|
||||
compute='_compute_details_by_salary_rule_category', string='Details by Salary Rule Category')
|
||||
credit_note = fields.Boolean(string='Credit Note', readonly=True,
|
||||
states={'draft': [('readonly', False)]},
|
||||
help="Indicates this payslip has a refund of another")
|
||||
@@ -68,11 +66,6 @@ class HrPayslip(models.Model):
|
||||
copy=False, states={'draft': [('readonly', False)]})
|
||||
payslip_count = fields.Integer(compute='_compute_payslip_count', string="Payslip Computation Details")
|
||||
|
||||
@api.multi
|
||||
def _compute_details_by_salary_rule_category(self):
|
||||
for payslip in self:
|
||||
payslip.details_by_salary_rule_category = payslip.mapped('line_ids').filtered(lambda line: line.category_id)
|
||||
|
||||
@api.multi
|
||||
def _compute_payslip_count(self):
|
||||
for payslip in self:
|
||||
|
||||
@@ -2,5 +2,4 @@
|
||||
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import report_payslip_details
|
||||
from . import report_contribution_register
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
class PayslipDetailsReport(models.AbstractModel):
|
||||
_name = 'report.hr_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('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)),
|
||||
}
|
||||
@@ -71,9 +71,6 @@ class TestPayslipFlow(TestPayslipBase):
|
||||
# I print the payslip report
|
||||
data, data_format = self.env.ref('hr_payroll.action_report_payslip').render(richard_payslip.ids)
|
||||
|
||||
# I print the payslip details report
|
||||
data, data_format = self.env.ref('hr_payroll.payslip_details_report').render(richard_payslip.ids)
|
||||
|
||||
# I print the contribution register report
|
||||
context = {'model': 'hr.contribution.register', 'active_ids': [self.ref('hr_payroll.hr_houserent_register')]}
|
||||
test_reports.try_report_action(self.env.cr, self.env.uid, 'action_payslip_lines_contribution_register', context=context, our_module='hr_payroll')
|
||||
|
||||
@@ -19,13 +19,4 @@
|
||||
print_report_name="'Payslip - %s' % (object.employee_id.name)"
|
||||
/>
|
||||
|
||||
<report
|
||||
id="payslip_details_report"
|
||||
model="hr.payslip"
|
||||
string="PaySlip Details"
|
||||
report_type="qweb-pdf"
|
||||
name="hr_payroll.report_payslipdetails"
|
||||
file="hr_payroll.report_payslipdetails"
|
||||
print_report_name="'Payslip Details - %s' % (object.employee_id.name)"
|
||||
/>
|
||||
</odoo>
|
||||
|
||||
@@ -230,17 +230,7 @@
|
||||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Details By Salary Rule Category">
|
||||
<field name="details_by_salary_rule_category" context="{'group_by':'category_id'}" domain="[('appears_on_payslip', '=', True)]">
|
||||
<tree string="Payslip Lines" decoration-info="total == 0">
|
||||
<field name="category_id"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="total"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Accounting Information">
|
||||
<page string="Accounting Information">
|
||||
<group>
|
||||
<group string="Miscellaneous">
|
||||
<field name="company_id" groups="base.group_multi_company"/>
|
||||
@@ -253,7 +243,7 @@
|
||||
<div colspan="4">
|
||||
<field name="note" placeholder="Add an internal note..."/>
|
||||
</div>
|
||||
</page>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="report_payslipdetails">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page">
|
||||
<h2>Pay Slip</h2>
|
||||
<p t-field="o.name"/>
|
||||
|
||||
<table class="table table-sm table-bordered">
|
||||
<tr>
|
||||
<td><strong>Name</strong></td>
|
||||
<td><span t-field="o.employee_id"/></td>
|
||||
<td><strong>Designation</strong></td>
|
||||
<td><span t-field="o.employee_id.job_id"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Address</strong></td>
|
||||
<td colspan="3">
|
||||
<div t-field="o.employee_id.address_home_id"
|
||||
t-options='{"widget": "contact", "fields": ["address", "name", "phone"], "no_marker": True, "phone_icons": True}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Email</strong></td>
|
||||
<td><span t-field="o.employee_id.work_email"/></td>
|
||||
<td><strong>Identification No</strong></td>
|
||||
<td><span t-field="o.employee_id.identification_id"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Reference</strong></td>
|
||||
<td><span t-field="o.number"/></td>
|
||||
<td><strong>Bank Account</strong></td>
|
||||
<td><span t-field="o.employee_id.bank_account_id"/></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><strong>Date From</strong></td>
|
||||
<td><span t-field="o.date_from"/></td>
|
||||
<td><strong>Date To</strong></td>
|
||||
<td><span t-field="o.date_to"/></td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Details by Salary Rule Category</h3>
|
||||
<table class="table table-sm mb32">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Code</th>
|
||||
<th>Salary Rule Category</th>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="get_details_by_rule_category.get(o.id, [])" t-as="h">
|
||||
<td>
|
||||
<span t-esc="h['code']"/>
|
||||
</td>
|
||||
<td>
|
||||
<span t-esc="'..'*h['level']"/><span t-esc="h['rule_category']"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="h['total']"
|
||||
t-esc-options='{"widget": "monetary", "display_currency": o.company_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3>Payslip Lines by Contribution Register</h3>
|
||||
<table class="table table-sm mt32">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Code</th>
|
||||
<th>Name</th>
|
||||
<th>Quantity/rate</th>
|
||||
<th>Amount</th>
|
||||
<th>Total</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="get_lines_by_contribution_register.get(o.id, [])" t-as="p">
|
||||
<td><span t-esc="p.get('code', '')"/></td>
|
||||
<td><span t-esc="p.get('name', '')"/></td>
|
||||
<td><span t-esc="p.get('quantity', '')"/></td>
|
||||
<td><span t-esc="p.get('amount', 0)"/></td>
|
||||
<td class="text-right">
|
||||
<span t-esc="p.get('total', 0)"
|
||||
t-esc-options='{"widget": "monetary", "display_currency": o.company_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<p class="text-right"><strong>Authorized signature</strong></p>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
@@ -69,7 +69,7 @@ class HrPayslip(models.Model):
|
||||
'journal_id': slip.journal_id.id,
|
||||
'date': date,
|
||||
}
|
||||
for line in slip.details_by_salary_rule_category:
|
||||
for line in slip.line_ids.filtered(lambda line: line.category_id):
|
||||
amount = slip.credit_note and -line.total or line.total
|
||||
if float_is_zero(amount, precision_digits=precision):
|
||||
continue
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from . import report_payslip_details
|
||||
from . import report_payroll_advice
|
||||
from . import report_hr_salary_employee_bymonth
|
||||
from . import payment_advice_report
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
#-*- coding:utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, models
|
||||
|
||||
|
||||
class PayslipDetailsReportIN(models.AbstractModel):
|
||||
_name = 'report.l10n_in_hr_payroll.report_payslipdetails'
|
||||
_inherit = 'report.hr_payroll.report_payslipdetails'
|
||||
|
||||
@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'))
|
||||
}
|
||||
Reference in New Issue
Block a user