From d706c9a70006d1bb9dc0bd1a26c46f7e7447cd6c Mon Sep 17 00:00:00 2001 From: younes Date: Wed, 24 Sep 2025 12:58:32 +0100 Subject: [PATCH] Payroll report notes --- odex25_hr/exp_payroll_custom/i18n/ar_001.po | 11 +++-- .../report/payslip_monthly_report.py | 44 +++++++++++-------- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/odex25_hr/exp_payroll_custom/i18n/ar_001.po b/odex25_hr/exp_payroll_custom/i18n/ar_001.po index 281c7f4d6..433c58760 100644 --- a/odex25_hr/exp_payroll_custom/i18n/ar_001.po +++ b/odex25_hr/exp_payroll_custom/i18n/ar_001.po @@ -214,13 +214,17 @@ msgstr "قيد لكل الموظفين" #. module: exp_payroll_custom #: code:addons/exp_payroll_custom/models/hr_salary_rules.py:0 #: model:ir.model.fields.selection,name:exp_payroll_custom.selection__hr_employee_reward__reward_type__allowance -#: model:ir.model.fields.selection,name:exp_payroll_custom.selection__hr_salary_rule_category__rule_type__allowance #: model_terms:ir.ui.view,arch_db:exp_payroll_custom.model_payslip_form_view #: model:ir.model.fields.selection,name:exp_payroll_custom.selection__payroll_bank_wiz__report_type__allowance #, python-format msgid "Allowance" msgstr "البدلات" +#. module: exp_payroll_custom +#: model:ir.model.fields.selection,name:exp_payroll_custom.selection__hr_salary_rule_category__rule_type__allowance +msgid "Allowance" +msgstr "الراتب" + #. module: exp_payroll_custom #: model:ir.model.fields,field_description:exp_payroll_custom.field_lines_ids_reward__advantage_id msgid "Allowance Employee" @@ -2480,7 +2484,7 @@ msgstr "الاجمالي" #: model_terms:ir.ui.view,arch_db:exp_payroll_custom.hr_payslip_run_report_pdf_template #: model_terms:ir.ui.view,arch_db:exp_payroll_custom.view_hr_payslip_inherit_tree msgid "Total Allowance" -msgstr "إجمالي البدلات" +msgstr "إجمالي الراتب" #. module: exp_payroll_custom #: model:ir.model.fields,field_description:exp_payroll_custom.field_hr_contract__total_deduction @@ -3010,4 +3014,5 @@ msgstr "مراجعة المالية" #. module: exp_payroll_custom #: model:res.groups,name:exp_payroll_custom.group_payroll_expense_manger msgid "Expense Manager" -msgstr "رئيس المصروفات" \ No newline at end of file +msgstr "رئيس المصروفات" + diff --git a/odex25_hr/exp_payroll_custom/report/payslip_monthly_report.py b/odex25_hr/exp_payroll_custom/report/payslip_monthly_report.py index 368786dd0..0eb911128 100644 --- a/odex25_hr/exp_payroll_custom/report/payslip_monthly_report.py +++ b/odex25_hr/exp_payroll_custom/report/payslip_monthly_report.py @@ -16,26 +16,28 @@ class PayslipMonthlyReport(models.AbstractModel): ftotal = 0 title = _('Allowances and deduction Totals') docs.append({'count': '#', 'rule': _('Name'), 'type': _('Type'), 'amount': _('Amount'), }) - for rule in self.env[data['model']].browse(data['ids']): + rules = self.env[data['model']].browse(data['ids']).sorted('sequence') + for rule in rules: count += 1 total = sum(payslip_line.browse(data['payslip_line_ids']).filtered( - lambda r: r.salary_rule_id.id == rule.id).mapped('amount')) + lambda r: r.salary_rule_id.id == rule.id).mapped('total')) ftotal += total docs.append({ 'count': count, 'rule': rule.name, 'type': _(dict(rule.category_id._fields['rule_type'].selection, context={}).get( rule.category_id.rule_type)), - 'amount': total, + 'amount': "{:.2f}".format(total), }) - docs.append({'count': '', 'rule': _('Total'), 'type': '', 'amount': ftotal, }) + docs.append({'count': '', 'rule': _('Total'), 'type': '', 'amount': "{:.2f}".format(ftotal), }) elif data['delist'] == 'tt': # TODO review bellow raise if not data['payslip_line_ids'] or not data['rule_ids']: raise ValidationError( _('Sorry No Data To Be Printed')) title = _('Employees Paysheet') rule_dict = {} - for line in self.env['hr.salary.rule'].browse(data['rule_ids']): + sorted_rules = self.env['hr.salary.rule'].browse(data['rule_ids']).sorted('sequence') + for line in sorted_rules: rule_dict.setdefault(line.category_id.rule_type, []) rule_dict[line.category_id.rule_type] += line tdict = {'count': '#', 'emp_no':_('EMP #'),'emp': _('Name'), } @@ -43,8 +45,10 @@ class PayslipMonthlyReport(models.AbstractModel): for key, value in rule_dict.items(): for x in value: tdict[x.id], ndict[x.id] = x.name, 0 - tdict[key], ndict[key] = _('Total ') + _( - dict(x.category_id._fields['rule_type'].selection, context={}).get(key)), 0 + rule_type_name = dict( + x.category_id._fields['rule_type']._description_selection(self.env) + ).get(key) + tdict[key], ndict[key] = _('%s %s') % (_('Total'), rule_type_name), 0 tdict['net'], ndict['net'], = _('Net'), 0 if self.env.context.get('track_emp', False): tdict['track_id'] = 'track_id' docs.append(tdict) @@ -69,7 +73,7 @@ class PayslipMonthlyReport(models.AbstractModel): elif isinstance(key, int): total = sum(payslip_line.browse(data['payslip_line_ids']).filtered( lambda r: r.employee_id.id == emp.id and r.salary_rule_id.id == key).mapped('total')) - emp_dict[key] = total + emp_dict[key] = "{:.2f}".format(total) net += total fnet += total ndict[key] += total @@ -77,26 +81,30 @@ class PayslipMonthlyReport(models.AbstractModel): total = sum(payslip_line.browse(data['payslip_line_ids']).filtered( lambda r: r.employee_id.id == emp.id and r.salary_rule_id.category_id.rule_type == key).mapped( - 'amount')) - emp_dict[key] = total + 'total')) + emp_dict[key] = "{:.2f}".format(total) ndict[key] += total elif isinstance(key, bool): total = sum(payslip_line.browse(data['payslip_line_ids']).filtered( lambda r: r.employee_id.id == emp.id and r.salary_rule_id.category_id.rule_type == False).mapped( 'total')) - emp_dict[key] = total + emp_dict[key] = "{:.2f}".format(total) ndict[key] += total if value == _('Net'): - emp_dict[key] = net + emp_dict[key] = "{:.2f}".format(net) continue docs.append(emp_dict) - ndict['net'] = fnet + for key in ndict: + if isinstance(ndict[key], (int, float)) and key not in ['count', 'emp_no', 'emp']: + ndict[key] = "{:.2f}".format(ndict[key]) + ndict['net'] = "{:.2f}".format(fnet) docs.append(ndict) else: title = _('Specific Allowance and deduction Report') exception = True - for rule in self.env[data['model']].browse(data['ids']): + rules = self.env[data['model']].browse(data['ids']).sorted('sequence') + for rule in rules: count = 0 ftotal = 0 inner_doc = {'rule': rule.name, 'lines': [], } @@ -105,10 +113,10 @@ class PayslipMonthlyReport(models.AbstractModel): lambda r: r.salary_rule_id.id == rule.id).mapped('employee_id')): count += 1 total = sum(payslip_line.browse(data['payslip_line_ids']).filtered( - lambda r: r.employee_id.id == emp.id and r.salary_rule_id.id == rule.id).mapped('amount')) + lambda r: r.employee_id.id == emp.id and r.salary_rule_id.id == rule.id).mapped('total')) ftotal += total - inner_doc['lines'].append({'count': count, 'emp_no': emp.emp_no, 'emp': emp.name, 'amount': total, }) - inner_doc['lines'].append({'count': '', 'emp_no': _('Total'),'emp':'', 'amount': ftotal, }) + inner_doc['lines'].append({'count': count, 'emp_no': emp.emp_no, 'emp': emp.name, 'amount': "{:.2f}".format(total), }) + inner_doc['lines'].append({'count': '', 'emp_no': _('Total'),'emp':'', 'amount': "{:.2f}".format(ftotal), }) docs.append(inner_doc) return title, exception, docs @@ -130,7 +138,7 @@ class PayslipMonthlyReportXlsx(models.AbstractModel): @api.model def generate_xlsx_report(self, workbook, data, objs): - title, exception, docs = PayslipMonthlyReport.get_rule_values(self, data) + title, exception, docs = self.env['report.exp_payroll_custom.payslip_monthly_report'].get_rule_values(data) sheet = workbook.add_worksheet('Proll Monthly report') format1 = workbook.add_format({'bottom': True, 'right': True, 'left': True, 'top': True, 'align': 'center', }) format2 = workbook.add_format({'font_size': 14, 'bottom': True, 'right': True, 'left': True, 'top': True,