forked from Mapan/odoo17e
108 lines
4.3 KiB
Python
108 lines
4.3 KiB
Python
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
|
|
|
from odoo.addons.hr_work_entry_contract_attendance.tests.common import HrWorkEntryAttendanceCommon
|
|
|
|
from datetime import datetime, date
|
|
|
|
from odoo.tests import tagged
|
|
|
|
@tagged('-at_install', 'post_install')
|
|
class TestPayslipAttendance(HrWorkEntryAttendanceCommon):
|
|
|
|
@classmethod
|
|
def setUpClass(cls):
|
|
super().setUpClass()
|
|
cls.struct_type = cls.env['hr.payroll.structure.type'].create({
|
|
'name': 'Test Structure Type',
|
|
'wage_type': 'hourly',
|
|
})
|
|
cls.struct = cls.env['hr.payroll.structure'].create({
|
|
'name': 'Test Structure - Worker',
|
|
'type_id': cls.struct_type.id,
|
|
})
|
|
cls.payslip = cls.env['hr.payslip'].create({
|
|
'name': 'Test Payslip',
|
|
'employee_id': cls.employee.id,
|
|
'struct_id': cls.struct.id,
|
|
'date_from': '2024-1-1',
|
|
'date_to': '2024-1-30',
|
|
})
|
|
|
|
def test_get_attendance_from_payslip(self):
|
|
attendance_A, attendance_B, *_ = self.env['hr.attendance'].create([
|
|
{
|
|
'employee_id': self.employee.id,
|
|
'check_in': datetime(2024, 1, 1, 8, 0, 0),
|
|
'check_out': datetime(2024, 1, 1, 16, 0, 0),
|
|
},
|
|
{
|
|
'employee_id': self.employee.id,
|
|
'check_in': datetime(2024, 1, 20, 8, 0, 0),
|
|
'check_out': datetime(2024, 1, 20, 16, 0, 0),
|
|
},
|
|
{
|
|
'employee_id': self.employee.id,
|
|
'check_in': datetime(2024, 2, 1, 8, 0, 0),
|
|
'check_out': datetime(2024, 2, 1, 16, 0, 0),
|
|
},
|
|
{
|
|
'employee_id': self.employee.id,
|
|
'check_in': datetime(2024, 2, 20, 8, 0, 0),
|
|
'check_out': datetime(2024, 2, 20, 16, 0, 0),
|
|
},
|
|
])
|
|
attendance_by_payslip = self.payslip._get_attendance_by_payslip()
|
|
self.assertEqual(attendance_by_payslip[self.payslip], attendance_A + attendance_B)
|
|
|
|
def test_get_attendance_from_payslip_with_timezone(self):
|
|
attendance_A, attendance_B, = self.env['hr.attendance'].create([
|
|
{
|
|
'employee_id': self.employee.id,
|
|
'check_in': datetime(2024, 1, 1, 7, 0, 0),
|
|
'check_out': datetime(2024, 1, 1, 15, 0, 0),
|
|
},
|
|
{
|
|
'employee_id': self.employee.id,
|
|
'check_in': datetime(2024, 1, 30, 23, 30, 0), # 2024-1-31 00-30-00 in UTC+1
|
|
'check_out': datetime(2024, 1, 31, 7, 30, 0),
|
|
},
|
|
])
|
|
|
|
# Without using `_get_attendance_by_payslip`
|
|
domain = [
|
|
('employee_id', '=', self.employee.id),
|
|
('check_in', '<=', self.payslip.date_to),
|
|
('check_out', '>=', self.payslip.date_from)
|
|
]
|
|
attendances = self.env['hr.attendance'].with_context(tz="Europe/Brussels").search(domain)
|
|
self.assertEqual(attendances, attendance_A + attendance_B) # Not correct (`attendance_B` is not in the payslip period)
|
|
# With using `_get_attendance_by_payslip`:
|
|
attendance_by_payslip = self.payslip.with_context(tz="Europe/Brussels")._get_attendance_by_payslip()
|
|
self.assertEqual(attendance_by_payslip[self.payslip], attendance_A) # Correct
|
|
|
|
def test_compute_payslip_no_worked_hours(self):
|
|
employee = self.env['hr.employee'].create({'name': 'John'})
|
|
contract = self.env['hr.contract'].create({
|
|
'name': 'Contract for John',
|
|
'wage': 5000,
|
|
'employee_id': employee.id,
|
|
'date_start': date(2024, 10, 1),
|
|
'date_end': date(2024, 10, 31),
|
|
'work_entry_source': 'attendance',
|
|
'structure_type_id': self.struct_type.id,
|
|
'state': 'open',
|
|
})
|
|
|
|
payslip = self.env['hr.payslip'].create({
|
|
'name': 'Payslip of John',
|
|
'employee_id': employee.id,
|
|
'contract_id': contract.id,
|
|
'struct_id': self.struct.id,
|
|
'date_from': date(2024, 10, 1),
|
|
'date_to': date(2024, 10, 31)
|
|
})
|
|
|
|
payslip.compute_sheet()
|
|
basic_salary_line = payslip.line_ids.filtered_domain([('code', '=', 'BASIC')])
|
|
self.assertAlmostEqual(basic_salary_line.amount, 0.0, 2, 'Basic salary = 0 worked hours * hourly wage = 0')
|