Skip to content
Permalink
Browse files

[IMP] l10n_be_hr_payroll: Add 'Individual account' report

Purpose
=======

Add the possibility to generate the 'Compte Individuel' (or 'Individual Account')
based on the belgian payslip for a specific year.

This report aggregates the payslip lines by month, by quarter and for the entire
year.
  • Loading branch information...
sed-odoo authored and tivisse committed Jan 3, 2019
1 parent 5062a26 commit 54c477aad668eedcfc96d10f583208007e04e326
@@ -57,7 +57,7 @@ def get_all_rules(self):
all_rules = []
for struct in self:
all_rules += struct.rule_ids._recursive_search_of_rules()
return all_rules
return list(set(all_rules))

@api.multi
def _get_parent_structure(self):
@@ -2,3 +2,5 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import models
from . import report
from . import wizard
@@ -25,7 +25,11 @@
'views/reports.xml',
'views/l10n_be_hr_payroll_view.xml',
'data/l10n_be_hr_payroll_data.xml',
'data/report_paperformat.xml',
'views/res_config_settings_views.xml',
'wizard/l10n_be_individual_account_wizard_views.xml',
'report/hr_individual_account_reports.xml',
'report/hr_individual_account_templates.xml',
],
'demo':[
'data/l10n_be_hr_payroll_demo.xml'
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="paperformat_individual_account" model="report.paperformat">
<field name="name">Individual Account</field>
<field name="default" eval="True"/>
<field name="format">custom</field>
<field name="page_height">297</field>
<field name="page_width">210</field>
<field name="orientation">Portrait</field>
<field name="margin_top">30</field>
<field name="margin_bottom">23</field>
<field name="margin_left">5</field>
<field name="margin_right">5</field>
<field name="header_line" eval="False"/>
<field name="header_spacing">20</field>
<field name="dpi">90</field>
</record>
</odoo>
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import hr_individual_account_reports
@@ -0,0 +1,88 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from collections import OrderedDict

from odoo import api, models, _
from odoo.fields import Datetime
from odoo.exceptions import UserError


class IndividualAccountReport(models.AbstractModel):
_name = 'report.l10n_be_hr_payroll.report_individual_account'
_description = 'Individual Account Report'

def _get_report_data(self, data):
year = data['year']
employees = self.env['hr.employee'].browse(data['employee_ids'])

payslips = self.env['hr.payslip'].search([
('employee_id', 'in', employees.ids),
('state', '=', 'done'),
('date_from', '>=', Datetime.now().replace(month=1, day=1, year=year)),
('date_from', '<=', Datetime.now().replace(month=12, day=31, year=year)),
'|',
('struct_id.country_id', '=', False),
('struct_id.country_id', '=', self.env.ref('base.be').id),
])
lines = payslips.mapped('line_ids')
payslip_rules = [(rule.code, rule.sequence) for rule in lines.mapped('salary_rule_id')]
payslip_rules = sorted(payslip_rules, key=lambda x: x[1])
worked_days = payslips.mapped('worked_days_line_ids')

result = {
employee: {
'rules': OrderedDict(
(rule[0], {
'year': {'name': False, 'total': 0},
'month': {m: {'name': False, 'total': 0} for m in range(12)},
'quarter': {q: {'name': False, 'total': 0} for q in range(4)}
}) for rule in payslip_rules),
'worked_days': {
code: {
'year': {'name': False, 'number_of_days': 0, 'number_of_hours': 0},
'month': {m: {'name': False, 'number_of_days': 0, 'number_of_hours': 0} for m in range(12)},
'quarter': {q: {'name': False, 'number_of_days': 0, 'number_of_hours': 0} for q in range(4)}
} for code in worked_days.mapped('code')
}
} for employee in employees
}

for line in lines:
rule = result[line.employee_id]['rules'][line.salary_rule_id.code]
month = line.slip_id.date_from.month - 1
rule['month'][month]['name'] = line.name
rule['month'][month]['total'] += line.total
rule['quarter'][(month) // 3]['name'] = line.name
rule['quarter'][(month) // 3]['total'] += line.total
rule['year']['name'] = line.name
rule['year']['total'] += line.total

rule['month'][month]['total'] = round(rule['month'][month]['total'], 2)
rule['quarter'][(month) // 3]['total'] = round(rule['quarter'][(month) // 3]['total'], 2)
rule['year']['total'] = round(rule['year']['total'], 2)

for worked_day in worked_days:
work = result[worked_day.payslip_id.employee_id]['worked_days'][worked_day.code]
month = worked_day.payslip_id.date_from.month - 1

work['month'][month]['name'] = worked_day.name
work['month'][month]['number_of_days'] += worked_day.number_of_days
work['month'][month]['number_of_hours'] += worked_day.number_of_hours
work['quarter'][(month) // 3]['name'] = worked_day.name
work['quarter'][(month) // 3]['number_of_days'] += worked_day.number_of_days
work['quarter'][(month) // 3]['number_of_hours'] += worked_day.number_of_hours
work['year']['name'] = worked_day.name
work['year']['number_of_days'] += worked_day.number_of_days
work['year']['number_of_hours'] += worked_day.number_of_hours

return {
'year': year,
'employee_data': result
}

@api.model
def _get_report_values(self, docids, data=None):
if self.env.user.company_id.country_id != self.env.ref('base.be'):
raise UserError(_("You must be logged into a Belgian company to print the individual account."))
return {'report_data': self._get_report_data(data)}
@@ -0,0 +1,18 @@
<?xml version="1.0"?>
<odoo>

<report
id="action_report_individual_account"
model="hr.employee"
string="Individual Account"
report_type="qweb-pdf"
name="l10n_be_hr_payroll.report_individual_account"
file="l10n_be_hr_payroll.report_individual_account"
print_report_name="(object._get_report_base_filename())"
/>
<record id="action_report_individual_account" model="ir.actions.report">
<field name="paperformat_id" ref="l10n_be_hr_payroll.paperformat_individual_account"/>
<field name="binding_model_id" eval="False"/>
</record>

</odoo>
Oops, something went wrong.

0 comments on commit 54c477a

Please sign in to comment.
You can’t perform that action at this time.