@@ -1,7 +1,8 @@
from odoo . tests . common import TransactionCase
from odoo . tests import tagged
from datetime import date , timedelta
from datetime import date , timedelta , datetime
from odoo . exceptions import UserError
from odoo . fields import Date
@tagged ( " post_install " , " -at_install " )
class TestHrEmployeeStatsRecovery ( TransactionCase ) :
@@ -19,6 +20,7 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
self . employee = self . env [ ' hr.employee ' ] . create ( {
' name ' : ' Camille ' ,
' user_id ' : self . user . id ,
' tz ' : ' Europe/Paris ' ,
} )
self . base_calendar = self . env [ ' resource.calendar ' ] . create ( {
' name ' : ' Default Calendar ' ,
@@ -35,11 +37,13 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
( 0 , 0 , { ' name ' : ' Friday Afternoon ' , ' dayofweek ' : ' 4 ' , ' hour_from ' : 13 , ' hour_to ' : 17 , ' day_period ' : ' afternoon ' } ) ,
] ,
} )
self . base_calendar . hours_per_day = 7
self . employee . resource_calendar_id = self . base_calendar
self . env . company . recovery_type_id = self . recovery_type
self . env . company . coef = 25
def _create_timesheet_sheet ( self , start_date ) :
#Crée une feuille de temps pour la semaine du lundi au dimanche
# Create a timesheet for the week (Monday to Sunday)
return self . env [ ' hr_timesheet.sheet ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : start_date ,
@@ -47,7 +51,7 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
} )
def _create_stats ( self , start_date , nb_days , unit_amount ) :
# Crée des temps du lundi au vendredi (ou nb_days)
# Create timesheet lines from Monday to Friday (or nb_days)
for i in range ( nb_days ) :
self . env [ ' account.analytic.line ' ] . create ( {
' employee_id ' : self . employee . id ,
@@ -56,16 +60,17 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
' account_id ' : 1 ,
' name ' : ' Work Entry ' ,
} )
# Génère les hr_ employee_ stats pour chaque jour de la pé riode
# Generate hr. employee. stats for each day of the pe riod
stat = self . env [ ' hr.employee.stats ' ] . create ( {
' employee_id ' : self . employee . id ,
' date ' : start_date + timedelta ( days = i ) ,
} )
stat . _compute_dayofweek ( )
stat . _compute_hours ( )
yield stat
def test_invalide_recovery_type ( self ) :
start_date = date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 7 ) # lundi de la semaine dernière
start_date = date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 7 ) # monday of last week
self . recovery_type . request_unit = ' day '
self . recovery_type . allows_negative = False
timesheet_sheet = self . _create_timesheet_sheet ( start_date )
@@ -74,7 +79,13 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
timesheet_sheet . action_generate_recovery_allocation ( )
def test_no_recovery_hours ( self ) :
start_date = date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 7 ) # lundi de la semaine dernière
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2025-01-01 " ) ,
' date_end ' : None ,
' calendar_id ' : self . base_calendar . id ,
} )
start_date = date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 7 ) # monday of last week
timesheet_sheet = self . _create_timesheet_sheet ( start_date )
for stat in self . _create_stats ( start_date , 5 , 7 ) : #créer 5 stats de 7h chacune
# Compare les heures de récupération calculées et le calendrier qui prévoit 7h par jour
@@ -88,6 +99,12 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
self . assertEqual ( timesheet_sheet . timesheet_sheet_recovery_hours , 0 , " timesheet_sheet_recovery_hours should be 0 " , )
def test_positive_recovery_hours ( self ) :
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2025-01-01 " ) ,
' date_end ' : None ,
' calendar_id ' : self . base_calendar . id ,
} )
start_date = date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 7 ) # lundi de la semaine dernière
timesheet_sheet = self . _create_timesheet_sheet ( start_date )
for stat in self . _create_stats ( start_date , 5 , 8 ) : #créer 5 stats de 8h chacune
@@ -104,9 +121,15 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
timesheet_sheet . action_generate_recovery_allocation ( )
recovery_allocation = self . env [ " hr.leave.allocation " ] . search ( [ ( " timesheet_sheet_id " , " = " , timesheet_sheet . id ) ] )
self . assertEqual ( len ( recovery_allocation ) , 1 , " There should be one recovery " )
self . assertEqual ( recovery_allocation . number_of_days , 0.78125 , " The recovery allocation should be for 6.25h/8 h = 0.78125 day " )
self . assertEqual ( recovery_allocation . number_of_days , 0.8928571428571429 , " The recovery allocation should be for 6.25h/7 h = 0.8928571428571429 day " )
def test_negative_recovery_hours ( self ) :
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2025-01-01 " ) ,
' date_end ' : None ,
' calendar_id ' : self . base_calendar . id ,
} )
start_date = date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 7 ) # lundi de la semaine dernière
timesheet_sheet = self . _create_timesheet_sheet ( start_date )
for stat in self . _create_stats ( start_date , 5 , 6 ) : #créer 5 stats de 6h chacune
@@ -123,7 +146,7 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
timesheet_sheet . action_generate_recovery_allocation ( )
recovery_allocation = self . env [ " hr.leave.allocation " ] . search ( [ ( " timesheet_sheet_id " , " = " , timesheet_sheet . id ) ] )
self . assertEqual ( len ( recovery_allocation ) , 1 , " There should be one recovery " )
self . assertEqual ( recovery_allocation . number_of_days , - 0.625 , " The recovery allocation should be for -5/8 hours = " )
self . assertEqual ( recovery_allocation . number_of_days , - 0.7142857142857143 , " The recovery allocation should be for -5/7 hours = − 0,714285714 " )
def test_recovery_hours_part_time_employee ( self ) :
part_time_calendar = self . env [ ' resource.calendar ' ] . create ( {
@@ -139,8 +162,12 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
( 0 , 0 , { ' name ' : ' Thursday Afternoon ' , ' dayofweek ' : ' 3 ' , ' hour_from ' : 13 , ' hour_to ' : 17 , ' day_period ' : ' afternoon ' } ) ,
] ,
} )
self . employee . resource_calendar_id = part_time_calendar . id
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2025-01-01 " ) ,
' date_end ' : None ,
' calendar_id ' : part_time_calendar . id ,
} )
start_date = date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 7 ) # lundi de la semaine dernière
timesheet_sheet = self . _create_timesheet_sheet ( start_date )
for stat in self . _create_stats ( start_date , 4 , 8 ) : #créer 4 stats de 8h chacune
@@ -154,8 +181,9 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
self . assertEqual ( timesheet_sheet . timesheet_sheet_gap_hours , 4 , " timesheet_sheet_gap_hours should be 4 " , ) # l'employé a travaillé supplémentaire 4h au total sur la semaine
self . assertEqual ( timesheet_sheet . timesheet_sheet_recovery_hours , 5 , " timesheet_sheet_recovery_hours should be 5 " , ) # 5h sera le montant de l'allocation de récupération (coef de 25% de majoration)
def test_recovery_hours_change_contract ( self ) :
part _time_calendar = self . env [ ' resource.calendar ' ] . create ( {
def test_recovery_hours_change_calendar ( self ) :
employee_full _time_calendar = self . base_calendar # full time calendar (from monday to friday)
employee_part_time_calendar = self . env [ ' resource.calendar ' ] . create ( {
' name ' : ' Part Time Calendar ' ,
' attendance_ids ' : [
( 0 , 0 , { ' name ' : ' Monday Morning ' , ' dayofweek ' : ' 0 ' , ' hour_from ' : 9 , ' hour_to ' : 12 , ' day_period ' : ' morning ' } ) ,
@@ -168,35 +196,31 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
( 0 , 0 , { ' name ' : ' Thursday Afternoon ' , ' dayofweek ' : ' 3 ' , ' hour_from ' : 13 , ' hour_to ' : 17 , ' day_period ' : ' afternoon ' } ) ,
] ,
} )
#create one contract ending on wednesday and one other starting on thursday
self . env [ ' hr.contract ' ] . create ( {
' name ' : ' Contract 1 ' ,
#create two hr.employee.calendar to change calendar during the timesheet period
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : d ate. today ( ) - timedelta ( days = 300 ) , # date de début factice
' date_end ' : d ate. today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 5 ) , # date de fin le mercredi de la semaine dernière
' resource_ calendar_id' : self . bas e_calendar. id ,
' wage ' : 2000 ,
' state ' : ' close ' ,
' date_start ' : D ate. to_ date ( " 2023-07-01 " ) ,
' date_end ' : D ate. to_ date ( " 2025-07-31 " ) ,
' calendar_id ' : employee_full_tim e_calendar. id ,
} )
self . env [ ' hr.contract ' ] . create ( {
' name ' : ' Contract 2 ' ,
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' state ' : ' open ' ,
' date_start ' : date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 4 ) , # date de début le jeudi de la semaine dernière
' date_end ' : False ,
' resource_calendar_id ' : self . base_calendar . id ,
' wage ' : 1500 ,
' date_ star t' : Date . to_date ( " 2025-08-01 " ) ,
' date_end ' : None ,
' calendar_id ' : employee_part_time_calendar . id ,
} )
self . employee . resource_calendar_id = part_time_calendar . id
start_date = date . today ( ) - timedelta ( days = date . today ( ) . weekday ( ) + 7 ) # lundi de la semaine dernière
#create a timesheet with period including the change of contract
timesheet_sheet = self . _create_timesheet_sheet ( start_date )
self . employee . resource_calendar_id = employee_ part_time_calendar. id
#create recovery hours on a period including the change of calendar
timesheet_sheet = self . _create_timesheet_sheet ( Date . to_date ( " 2025-07-28 " ) ) #a week including the change of calendar on 1st august
#the create of recovery allocation should raise an error
with self . assertRaises ( UserError ) :
timesheet_sheet . action_generate_recovery_allocation ( )
def test_recovery_hours_change_contract _sucess ( self ) :
part _time_calendar = self . env [ ' resource.calendar ' ] . create ( {
def test_recovery_hours_change_calendar _sucess ( self ) :
employee_full _time_calendar = self . base_calendar # full time calendar (from monday to friday)
employee_part_time_calendar = self . env [ ' resource.calendar ' ] . create ( {
' name ' : ' Part Time Calendar ' ,
' attendance_ids ' : [
( 0 , 0 , { ' name ' : ' Monday Morning ' , ' dayofweek ' : ' 0 ' , ' hour_from ' : 9 , ' hour_to ' : 12 , ' day_period ' : ' morning ' } ) ,
@@ -209,39 +233,160 @@ class TestHrEmployeeStatsRecovery(TransactionCase):
( 0 , 0 , { ' name ' : ' Thursday Afternoon ' , ' dayofweek ' : ' 3 ' , ' hour_from ' : 13 , ' hour_to ' : 17 , ' day_period ' : ' afternoon ' } ) ,
] ,
} )
#create one contract ending on wednesday and one other starting on thursday
self . env [ ' hr.contract ' ] . create ( {
' name ' : ' Contract 1 ' ,
' employee_id ' : self . employee . id ,
' date_start ' : date ( 2025 , 8 , 18 ) ,
' date_end ' : date ( 2025 , 8 , 24 ) ,
' resource_calendar_id ' : self . base_calendar . id ,
' wage ' : 2000 ,
' state ' : ' close ' ,
} )
self . env [ ' hr.contract ' ] . create ( {
' name ' : ' Contract 2 ' ,
' employee_id ' : self . employee . id ,
' state ' : ' open ' ,
' date_start ' : date ( 2025 , 8 , 25 ) ,
' date_end ' : date ( 2025 , 8 , 31 ) ,
' resource_calendar_id ' : part_time_calendar . id ,
' wage ' : 1500 ,
} )
self . employee . resource_calendar_id = part_time_calendar . id
#create a timesheet with period including the change of contract
timesheet_sheet_1 = self . _create_timesheet_sheet ( date ( 2025 , 8 , 18 ) )
timesheet_sheet_2 = self . _create_timesheet_sheet ( date ( 2025 , 8 , 25 ) )
#create two hr.employee.calendar to change calendar during the timesheet period
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2023-07-01 " ) ,
' date_end ' : Date . to_date ( " 2025-07-31 " ) ,
' calendar_id ' : employee_full_time_calendar . id ,
} )
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2025-08-01 " ) ,
' date_end ' : None ,
' calendar_id ' : employee_part_time_calendar . id ,
} )
self . employee . resource_calendar_id = employee_part_time_calendar . id
#create stats during period of full time calendar for the employee
timesheet_sheet = self . env [ ' hr_timesheet.sheet ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : " 2025-07-07 " ,
' date_end ' : " 2025-07-13 " ,
} )
stats = self . _create_stats ( Date . to_date ( " 2025-07-07 " ) , 5 , 7 )
for stat in stats :
stat . _compute_dayofweek ( )
stat . _compute_hours ( )
print ( " stat : " , stat . date , stat . total_hours , stat . total_planned_hours , stat . gap_hours )
timesheet_sheet . action_generate_recovery_allocation ( )
self . assertEqual ( timesheet_sheet . timesheet_sheet_gap_hours , 0 , " timesheet_sheet_gap_hours should be 0 " , )
self . assertEqual ( timesheet_sheet . timesheet_sheet_recovery_hours , 0 , " timesheet_sheet_recovery_hours should be 0 " , )
#create stats during period of part time calendar for the employee
stats = self . _create_stats ( Date . to_date ( " 2025-09-08 " ) , 5 , 7 )
for stat in stats :
stat . _compute_dayofweek ( )
stat . _compute_hours ( )
timesheet_sheet = self . env [ ' hr_timesheet.sheet ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : " 2025-09-08 " ,
' date_end ' : " 2025-09-14 " ,
} )
self . assertEqual ( timesheet_sheet . timesheet_sheet_gap_hours , 7 , " timesheet_sheet_gap_hours should be 7 " , )
self . assertEqual ( timesheet_sheet . timesheet_sheet_recovery_hours , 8.75 , " timesheet_sheet_recovery_hours should be 8,75 " , )
def test_recovery_allocation_doesnt_change_with_of_calendar ( self ) :
employee_full_time_calendar = self . base_calendar # full time calendar (from monday to friday)
employee_full_time_calendar . hours_per_day = 7
employee_part_time_calendar = self . env [ ' resource.calendar ' ] . create ( {
' name ' : ' Part Time Calendar ' ,
' attendance_ids ' : [
( 0 , 0 , { ' name ' : ' Monday Morning ' , ' dayofweek ' : ' 0 ' , ' hour_from ' : 9 , ' hour_to ' : 12 , ' day_period ' : ' morning ' } ) ,
( 0 , 0 , { ' name ' : ' Monday Afternoon ' , ' dayofweek ' : ' 0 ' , ' hour_from ' : 13 , ' hour_to ' : 19 , ' day_period ' : ' afternoon ' } ) ,
( 0 , 0 , { ' name ' : ' Tuesday Morning ' , ' dayofweek ' : ' 1 ' , ' hour_from ' : 9 , ' hour_to ' : 12 , ' day_period ' : ' morning ' } ) ,
( 0 , 0 , { ' name ' : ' Tuesday Afternoon ' , ' dayofweek ' : ' 1 ' , ' hour_from ' : 13 , ' hour_to ' : 19 , ' day_period ' : ' afternoon ' } ) ,
( 0 , 0 , { ' name ' : ' Wednesday Morning ' , ' dayofweek ' : ' 2 ' , ' hour_from ' : 9 , ' hour_to ' : 12 , ' day_period ' : ' morning ' } ) ,
( 0 , 0 , { ' name ' : ' Wednesday Afternoon ' , ' dayofweek ' : ' 2 ' , ' hour_from ' : 13 , ' hour_to ' : 19 , ' day_period ' : ' afternoon ' } ) ,
( 0 , 0 , { ' name ' : ' Thursday Morning ' , ' dayofweek ' : ' 3 ' , ' hour_from ' : 9 , ' hour_to ' : 12 , ' day_period ' : ' morning ' } ) ,
( 0 , 0 , { ' name ' : ' Thursday Afternoon ' , ' dayofweek ' : ' 3 ' , ' hour_from ' : 13 , ' hour_to ' : 19 , ' day_period ' : ' afternoon ' } ) ,
] ,
} )
employee_part_time_calendar . hours_per_day = 9
#create two hr.employee.calendar to change calendar during the timesheet period
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2023-07-01 " ) ,
' date_end ' : Date . to_date ( " 2025-07-31 " ) ,
' calendar_id ' : employee_full_time_calendar . id ,
} )
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2025-08-01 " ) ,
' date_end ' : None ,
' calendar_id ' : employee_part_time_calendar . id ,
} )
self . employee . resource_calendar_id = employee_part_time_calendar . id
#create stats during period of full time calendar for the employee
timesheet_sheet_1 = self . env [ ' hr_timesheet.sheet ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : " 2025-07-07 " ,
' date_end ' : " 2025-07-13 " ,
} )
stats = self . _create_stats ( Date . to_date ( " 2025-07-07 " ) , 5 , 8 )
for stat in stats :
stat . _compute_dayofweek ( )
stat . _compute_hours ( )
print ( " stat : " , stat . date , stat . total_hours , stat . total_planned_hours , stat . gap_hours )
timesheet_sheet_1 . action_generate_recovery_allocation ( )
self . assertEqual ( timesheet_sheet_1 . timesheet_sheet_gap_hours , 5 , " timesheet_sheet_gap_hours should be 0 " , )
self . assertEqual ( timesheet_sheet_1 . timesheet_sheet_recovery_hours , 6.25 , " timesheet_sheet_recovery_hours should be 6,25 " , )
allocation_1 = self . env [ " hr.leave.allocation " ] . search ( [ ( " timesheet_sheet_id " , " = " , timesheet_sheet_1 . id ) ] )
self . assertEqual ( len ( allocation_1 ) , 1 , " There should be one recovery " )
self . assertEqual ( allocation_1 . number_of_days , 0.8928571428571429 , " The recovery allocation should be for 0.8928571428571429 day " )
#create stats during period of part time calendar for the employee
# generation 4 stats of 10h each, the employee is supposed to work 9h per day during 4 days
stats_2 = self . _create_stats ( Date . to_date ( " 2025-09-08 " ) , 4 , 10 )
for stat in stats_2 :
stat . _compute_dayofweek ( )
stat . _compute_hours ( )
timesheet_sheet_2 = self . env [ ' hr_timesheet.sheet ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : " 2025-09-08 " ,
' date_end ' : " 2025-09-14 " ,
} )
timesheet_sheet_2 . action_generate_recovery_allocation ( )
self . assertEqual ( timesheet_sheet_2 . timesheet_sheet_gap_hours , 4 , " timesheet_sheet_gap_hours should be 4 " , )
self . assertEqual ( timesheet_sheet_2 . timesheet_sheet_recovery_hours , 5 , " timesheet_sheet_recovery_hours should be 5 " , )
allocation_2 = self . env [ " hr.leave.allocation " ] . search ( [ ( " timesheet_sheet_id " , " = " , timesheet_sheet_2 . id ) ] )
self . assertEqual ( len ( allocation_2 ) , 1 , " There should be one recovery " )
self . assertEqual ( allocation_2 . number_of_days , 0.5555555555555556 , " The recovery allocation should be for 0,555555556 (5/9) day " )
#check that allocation_1 hasn't changed
self . assertEqual ( allocation_1 . number_of_days , 0.8928571428571429 , " The recovery allocation should be for 0,892857143 day " )
recovery_allocation = self . env [ " hr.leave.allocation " ] . search ( [ ( " timesheet_sheet_id " , " = " , timesheet_sheet_1 . id ) ] )
self . assertEqual ( len ( recovery_allocation ) , 1 , " There should be one recovery " )
recovery_allocation = self . env [ " hr.leave.allocation " ] . search ( [ ( " timesheet_sheet_id " , " = " , timesheet_sheet_2 . id ) ] )
self . assertEqual ( len ( recovery_allocation ) , 1 , " There should be one recovery " )
def test_public_holiday ( self ) :
self . env [ ' hr.employee.calendar ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : Date . to_date ( " 2025-01-01 " ) ,
' date_end ' : None ,
' calendar_id ' : self . base_calendar . id ,
} )
# create a public holiday :
# When you create holidays graphically with a TZ,
# they are saved in the database after conversion to UTC.
# This is why, for a holiday starting on May 1, 2025, at 00:00:00 UTC+2,
# it will be saved in the database as April 30, 2025, at 22:00:00.
self . env [ " resource.calendar.leaves " ] . create (
{
" name " : " 1 mai 2025 " ,
" date_from " : datetime ( 2025 , 4 , 30 , 22 , 0 , 0 ) ,
" date_to " : datetime ( 2025 , 5 , 1 , 21 , 0 , 0 ) ,
}
)
#create 5 stats of 7h each including the public holiday on 1st may
stats = self . _create_stats ( Date . to_date ( " 2025-04-28 " ) , 5 , 7 )
for stat in stats :
stat . _compute_dayofweek ( )
stat . _compute_hours ( )
#create 1 timesheet sheet from monday to friday including the public holiday on 1st may
timesheet_sheet = self . env [ ' hr_timesheet.sheet ' ] . create ( {
' employee_id ' : self . employee . id ,
' date_start ' : " 2025-04-28 " ,
' date_end ' : " 2025-05-04 " ,
} )
# the employee has worked 7h on first may (public holiday) instead of 0h
# so the gap hours should be 7h and recovery hours 8,75h with coef 25%
self . assertEqual ( timesheet_sheet . timesheet_sheet_gap_hours , 7 , " timesheet_sheet_gap_hours should be 7 " , )
self . assertEqual ( timesheet_sheet . timesheet_sheet_recovery_hours , 8.75 , " timesheet_sheet_recovery_hours should be 8,75 " , )
timesheet_sheet . action_generate_recovery_allocation ( )
recovery_allocation = self . env [ " hr.leave.allocation " ] . search ( [ ( " timesheet_sheet_id " , " = " , timesheet_sheet . id ) ] )
self . assertEqual ( len ( recovery_allocation ) , 1 , " Il doit y avoir une allocation de récupération générée " )
self . assertEqual ( recovery_allocation . number_of_days , 1.25 , " The recovery allocation should be 1,25 days " )