diff --git a/hr_payroll_attendance/__manifest__.py b/hr_payroll_attendance/__manifest__.py index bb68d371..368e760d 100755 --- a/hr_payroll_attendance/__manifest__.py +++ b/hr_payroll_attendance/__manifest__.py @@ -1,10 +1,12 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + { 'name': 'Attendance on Payslips', 'description': 'Get Attendence numbers onto Employee Payslips.', - 'version': '13.0.1.0.0', + 'version': '13.0.1.0.1', 'website': 'https://hibou.io/', 'author': 'Hibou Corp. ', - 'license': 'AGPL-3', + 'license': 'OPL-1', 'category': 'Human Resources', 'data': [ 'data/hr_payroll_attendance_data.xml', @@ -17,6 +19,7 @@ 'hr_attendance', 'hr_attendance_work_entry', 'hr_payroll_overtime', + 'hibou_professional', ], 'pre_init_hook': 'attn_payroll_pre_init_hook', } diff --git a/hr_payroll_attendance/migrations/13.0.0.0.1/pre-migration.py b/hr_payroll_attendance/migrations/13.0.0.0.1/pre-migration.py index 6c081185..c04e9319 100644 --- a/hr_payroll_attendance/migrations/13.0.0.0.1/pre-migration.py +++ b/hr_payroll_attendance/migrations/13.0.0.0.1/pre-migration.py @@ -1,3 +1,4 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. def migrate(cr, version): # pre_init_hook script only runs on install, diff --git a/hr_payroll_attendance/models/hr_attendance.py b/hr_payroll_attendance/models/hr_attendance.py index 7c005f72..f668a82e 100644 --- a/hr_payroll_attendance/models/hr_attendance.py +++ b/hr_payroll_attendance/models/hr_attendance.py @@ -1,3 +1,5 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from odoo import fields, models diff --git a/hr_payroll_attendance/models/hr_contract.py b/hr_payroll_attendance/models/hr_contract.py index c6a70483..31226a99 100755 --- a/hr_payroll_attendance/models/hr_contract.py +++ b/hr_payroll_attendance/models/hr_contract.py @@ -1,3 +1,5 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from odoo import models, fields diff --git a/hr_payroll_attendance/models/hr_payslip.py b/hr_payroll_attendance/models/hr_payslip.py index 50584bdb..30504d27 100755 --- a/hr_payroll_attendance/models/hr_payslip.py +++ b/hr_payroll_attendance/models/hr_payslip.py @@ -1,3 +1,5 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from collections import defaultdict from odoo import api, fields, models, _ @@ -53,6 +55,9 @@ class HrPayslip(models.Model): # filter out "work calendar lines" worked_day_lines = [w for w in worked_day_lines if w['work_entry_type_id'] != original_work_type.id] + # normalize leaves + self._attendance_normalize_other_work_lines(worked_day_lines) + work_data = self._pre_aggregate_attendance_data(attendance_type) processed_data = self.aggregate_overtime(work_data) @@ -66,6 +71,16 @@ class HrPayslip(models.Model): return worked_day_lines + def _attendance_normalize_other_work_lines(self, worked_day_line_values): + # Modifies the values based on 'wage' + unpaid_work_entry_types = self.struct_id.unpaid_work_entry_type_ids + for line_vals in worked_day_line_values: + work_type = self.env['hr.work.entry.type'].browse(line_vals['work_entry_type_id']) + if work_type not in unpaid_work_entry_types: + line_vals['amount'] = line_vals.get('number_of_hours', 0.0) * self._wage_for_work_type(work_type) + else: + line_vals['amount'] = 0.0 + def _wage_for_work_type(self, work_type): # Override if you pay differently for different work types return self.contract_id.wage diff --git a/hr_payroll_attendance/tests/test_payroll_attendance.py b/hr_payroll_attendance/tests/test_payroll_attendance.py index b94df0ff..4bd80c8d 100644 --- a/hr_payroll_attendance/tests/test_payroll_attendance.py +++ b/hr_payroll_attendance/tests/test_payroll_attendance.py @@ -1,3 +1,5 @@ +# Part of Hibou Suite Professional. See LICENSE_PROFESSIONAL file for full copyright and licensing details. + from collections import defaultdict from odoo.tests import common @@ -25,6 +27,18 @@ class TestUsPayslip(common.TransactionCase): 'date_from': '2020-01-06', 'date_to': '2020-01-19', }) + self.work_entry_type_leave = self.env['hr.work.entry.type'].create({ + 'name': 'Test PTO', + 'code': 'TESTPTO', + 'is_leave': True, + }) + self.leave_type = self.env['hr.leave.type'].create({ + 'name': 'Test Paid Time Off', + 'time_type': 'leave', + 'allocation_type': 'no', + 'validity_start': False, + 'work_entry_type_id': self.work_entry_type_leave.id, + }) def _setup_attendance(self, employee): # Total 127.37 hours in 2 weeks. @@ -137,3 +151,27 @@ class TestUsPayslip(common.TransactionCase): self.payslip.compute_sheet() cats = self._getCategories() self.assertAlmostEqual(cats['BASIC'], 3247.68, 2) + + def test_with_leave(self): + date_from = '2020-01-10' + date_to = '2020-01-11' + leave = self.env['hr.leave'].create({ + 'name': 'Test Leave', + 'employee_id': self.employee.id, + 'holiday_status_id': self.leave_type.id, + 'date_to': date_to, + 'date_from': date_from, + 'number_of_days': 1, + }) + leave.action_validate() + self.assertEqual(leave.state, 'validate') + self.payslip._onchange_employee() + self.assertTrue(self.payslip.contract_id, 'No auto-discovered contract!') + self.payslip.compute_sheet() + self.assertTrue(self.payslip.worked_days_line_ids) + + leave_line = self.payslip.worked_days_line_ids.filtered(lambda l: l.code == 'TESTPTO') + self.assertTrue(leave_line) + self.assertEqual(leave_line.number_of_days, 1.0) + self.assertEqual(leave_line.number_of_hours, 8.0) + self.assertEqual(leave_line.amount, 8.0 * self.test_hourly_wage)