[IMP]hr_negative_leave:add tests
Some checks failed
pre-commit / pre-commit (pull_request) Failing after 1m29s
Some checks failed
pre-commit / pre-commit (pull_request) Failing after 1m29s
This commit is contained in:
@@ -15,27 +15,11 @@ class HolidaysType(models.Model):
|
|||||||
allows_negative = fields.Boolean(string='Allow Negative Leaves',
|
allows_negative = fields.Boolean(string='Allow Negative Leaves',
|
||||||
help="If checked, users request can exceed the allocated days and balance can go in negative.")
|
help="If checked, users request can exceed the allocated days and balance can go in negative.")
|
||||||
|
|
||||||
remaining_leaves_allowing_negative = fields.Float(
|
|
||||||
string="Remaining Leaves when Negative Allowed",
|
|
||||||
compute='_compute_remaining_leaves_allowing_negative',
|
|
||||||
)
|
|
||||||
|
|
||||||
def _compute_remaining_leaves_allowing_negative(self):
|
|
||||||
for holiday_type in self:
|
|
||||||
if holiday_type.allows_negative:
|
|
||||||
# if left != usable : remaining_leaves_allowing_negative = left + usable
|
|
||||||
if holiday_type.virtual_remaining_leaves < 0 (holiday_type.max_leaves - holiday_type.virtual_leaves_taken) != holiday_type.virtual_remaining_leaves:
|
|
||||||
holiday_type.remaining_leaves_allowing_negative = holiday_type.max_leaves - holiday_type.virtual_leaves_taken + holiday_type.virtual_remaining_leaves
|
|
||||||
else:
|
|
||||||
# else : remaining_leaves_allowing_negative = left as usual
|
|
||||||
holiday_type.remaining_leaves_allowing_negative = holiday_type.max_leaves - holiday_type.virtual_leaves_taken
|
|
||||||
else:
|
|
||||||
holiday_type.remaining_leaves_allowing_negative = None
|
|
||||||
|
|
||||||
@api.depends('requires_allocation')
|
@api.depends('requires_allocation')
|
||||||
def _compute_valid(self):
|
def _compute_valid(self):
|
||||||
res = super()._compute_valid()
|
res = super()._compute_valid()
|
||||||
for holiday_type in res:
|
for holiday_type in res:
|
||||||
|
#if negative is allowed, then the holiday type is valid in any case
|
||||||
if not holiday_type.has_valid_allocation:
|
if not holiday_type.has_valid_allocation:
|
||||||
holiday_type.has_valid_allocation = holiday_type.allows_negative
|
holiday_type.has_valid_allocation = holiday_type.allows_negative
|
||||||
|
|
||||||
@@ -155,9 +139,9 @@ class HolidaysType(models.Model):
|
|||||||
continue
|
continue
|
||||||
# calculate the number of days/hours for this allocation (allocation days/hours - leaves already taken)
|
# calculate the number of days/hours for this allocation (allocation days/hours - leaves already taken)
|
||||||
virtual_remaining_leaves = (available_allocation.number_of_days if leave_unit == 'days' else available_allocation.number_of_hours_display) - allocations_days_consumed[employee_id][holiday_status_id][available_allocation]['virtual_leaves_taken']
|
virtual_remaining_leaves = (available_allocation.number_of_days if leave_unit == 'days' else available_allocation.number_of_hours_display) - allocations_days_consumed[employee_id][holiday_status_id][available_allocation]['virtual_leaves_taken']
|
||||||
###########################################
|
#############################################
|
||||||
# Modification for leaves allowing negative #
|
# Modification for leaves allowing negative #
|
||||||
###########################################
|
#############################################
|
||||||
# if negative is allowed for this leave type, we can exceed the number of available days in this allocation
|
# if negative is allowed for this leave type, we can exceed the number of available days in this allocation
|
||||||
if holiday_status_id.allows_negative:
|
if holiday_status_id.allows_negative:
|
||||||
max_leaves = leave_duration
|
max_leaves = leave_duration
|
||||||
@@ -165,6 +149,9 @@ class HolidaysType(models.Model):
|
|||||||
# if negative is not allowed for this leave type, then we cannot exceed the allocation amount
|
# if negative is not allowed for this leave type, then we cannot exceed the allocation amount
|
||||||
# the max leaves for this allocation is the minimum between the remaining available days and the leave duration
|
# the max leaves for this allocation is the minimum between the remaining available days and the leave duration
|
||||||
max_leaves = min(virtual_remaining_leaves, leave_duration)
|
max_leaves = min(virtual_remaining_leaves, leave_duration)
|
||||||
|
####################################################
|
||||||
|
# END OF Modification for leaves allowing negative #
|
||||||
|
####################################################
|
||||||
# the new calculation of days taken for this allocation is previous taken + max_leaves (which can never exceed the allocation total)
|
# the new calculation of days taken for this allocation is previous taken + max_leaves (which can never exceed the allocation total)
|
||||||
days_consumed[available_allocation]['virtual_leaves_taken'] += max_leaves
|
days_consumed[available_allocation]['virtual_leaves_taken'] += max_leaves
|
||||||
if leave.state == 'validate':
|
if leave.state == 'validate':
|
||||||
|
|||||||
1
hr_negative_leave/tests/__init__.py
Normal file
1
hr_negative_leave/tests/__init__.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
from . import test_hr_negative_leave
|
||||||
91
hr_negative_leave/tests/test_hr_negative_leave.py
Normal file
91
hr_negative_leave/tests/test_hr_negative_leave.py
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
from datetime import date, timedelta
|
||||||
|
|
||||||
|
from odoo.tests import tagged
|
||||||
|
from odoo.tests.common import TransactionCase
|
||||||
|
from odoo.exceptions import UserError
|
||||||
|
|
||||||
|
|
||||||
|
@tagged('post_install', '-at_install')
|
||||||
|
class TestHrNegativeLeave(TransactionCase):
|
||||||
|
def setUp(self):
|
||||||
|
super().setUp()
|
||||||
|
|
||||||
|
# create a simple employee
|
||||||
|
self.employee = self.env['hr.employee'].create({
|
||||||
|
'name': 'NegTest Employee',
|
||||||
|
})
|
||||||
|
# create a user
|
||||||
|
self.user = self.env['res.users'].create({
|
||||||
|
'name': 'Test user',
|
||||||
|
'login': 'test user',
|
||||||
|
'employee_id': self.employee.id,
|
||||||
|
})
|
||||||
|
# prepare a leave type and an allocation with 1 day available
|
||||||
|
self.leave_type = self.env['hr.leave.type'].create({
|
||||||
|
'name': 'NegTest Type',
|
||||||
|
'request_unit': 'day',
|
||||||
|
'requires_allocation': 'yes',
|
||||||
|
'allows_negative': False,
|
||||||
|
})
|
||||||
|
self.allocation = self.env['hr.leave.allocation'].create({
|
||||||
|
'name': 'Alloc 1d',
|
||||||
|
'employee_id': self.employee.id,
|
||||||
|
'holiday_status_id': self.leave_type.id,
|
||||||
|
'number_of_days': 1.0,
|
||||||
|
'date_from': date.today() - timedelta(days=1),
|
||||||
|
'allocation_type': 'regular',
|
||||||
|
})
|
||||||
|
|
||||||
|
def test_negative_not_allowed_raises(self):
|
||||||
|
|
||||||
|
self.allocation.action_validate()
|
||||||
|
#self.leave_type._compute_leaves()
|
||||||
|
|
||||||
|
"""If the leave type does NOT allow negative, trying to confirm a leave
|
||||||
|
that exceeds allocations should raise a UserError."""
|
||||||
|
leave = self.env['hr.leave'].create({
|
||||||
|
'name': 'Too many days',
|
||||||
|
'employee_id': self.employee.id,
|
||||||
|
'holiday_status_id': self.leave_type.id,
|
||||||
|
'request_date_from': date.today(),
|
||||||
|
'request_date_to': date.today() + timedelta(days=1),
|
||||||
|
'number_of_days': 2.0,
|
||||||
|
'state': 'draft',
|
||||||
|
})
|
||||||
|
# self.leave_type._compute_leaves()
|
||||||
|
|
||||||
|
with self.assertRaises(UserError):
|
||||||
|
leave.write({'state': 'validate'})
|
||||||
|
|
||||||
|
def test_negative_allowed_allows_excess(self):
|
||||||
|
|
||||||
|
self.env.user = self.user
|
||||||
|
self.env.user.employee_id = self.employee
|
||||||
|
|
||||||
|
self.allocation.action_validate()
|
||||||
|
|
||||||
|
"""If the leave type allows negative, confirming a leave that exceeds
|
||||||
|
allocations must NOT raise an error."""
|
||||||
|
# flip the flag on the leave type
|
||||||
|
self.leave_type.allows_negative = True
|
||||||
|
leave = self.env['hr.leave'].create({
|
||||||
|
'name': 'Too many days',
|
||||||
|
'employee_id': self.employee.id,
|
||||||
|
'holiday_status_id': self.leave_type.id,
|
||||||
|
'date_from': date.today(),
|
||||||
|
'date_to': date.today() + timedelta(days=1),
|
||||||
|
'number_of_days': 2.0,
|
||||||
|
'state': 'draft',
|
||||||
|
})
|
||||||
|
# should not raise
|
||||||
|
leave.write({'state': 'confirm'})
|
||||||
|
|
||||||
|
# check remaining leaves is negative
|
||||||
|
self.leave_type._compute_leaves()
|
||||||
|
|
||||||
|
# Allocated in time off popup (Alloué)
|
||||||
|
self.assertEqual(self.leave_type.max_leaves, 1, "max_leaves should be 1",)
|
||||||
|
# Approuved in time off popup (Approuvé)
|
||||||
|
self.assertEqual(self.leave_type.virtual_leaves_taken, 2, "virtual_leaves_taken should be 2",)
|
||||||
|
# Remaining in time off popup (Restants)
|
||||||
|
self.assertEqual(self.leave_type.max_leaves - self.leave_type.virtual_leaves_taken, -1, "remaining leaves should display in timeoff popup -1",)
|
||||||
Reference in New Issue
Block a user