Files
enterprise-addons/timesheet_grid/tests/test_analytic_line.py
T

134 lines
5.9 KiB
Python

# Part of Odoo. See LICENSE file for full copyright and licensing details.
from datetime import date, datetime, time
from odoo.exceptions import UserError
from odoo.addons.hr_timesheet.tests.test_timesheet import TestCommonTimesheet
class TestAnalyticLine(TestCommonTimesheet):
def test_check_timesheet_unit_amount(self):
AccountAnalyticLine = self.env['account.analytic.line'].with_context(default_name='/')
timesheet, analytic_line = AccountAnalyticLine.create([
{
'project_id': self.project_customer.id,
'employee_id': self.empl_employee.id,
'unit_amount': 1,
},
{
'account_id': self.project_customer.account_id.id,
'unit_amount': 1000000,
},
])
for value in (1000000, -1000000):
with self.assertRaisesRegex(UserError, "You can't encode numbers with more than six digits."):
AccountAnalyticLine.create({
'project_id': self.project_customer.id,
'employee_id': self.empl_employee.id,
'unit_amount': value,
})
with self.assertRaisesRegex(UserError, "You can't encode numbers with more than six digits."):
timesheet.unit_amount = value
self.assertEqual(analytic_line.unit_amount, 1000000, "The user can enter a number with more than 6 digits for the analytic line which is not a timesheet.")
analytic_line.unit_amount = 1000005
self.assertEqual(analytic_line.unit_amount, 1000005, "The user can always alter the analytic to put the number he wants since it is not a timesheet.")
def test_timesheet_unavailabilities(self):
"""
Test that unavailabilities are based on current user's calendar if no groupby is provided
"""
calendar_emp = self.env['resource.calendar'].create({
'name': 'Monday Only Calendar',
'attendance_ids': [
(0, 0, {'name': 'Monday', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 16, 'day_period': 'morning'}),
],
})
test_user = self.env['res.users'].create({
'name': 'Test Employee User',
'login': 'test_emp_user',
'group_ids': [(4, self.env.ref('base.group_user').id)],
})
self.env['hr.employee'].create({
'name': 'Test Employee',
'user_id': test_user.id,
'resource_calendar_id': calendar_emp.id,
})
start_date = '2026-04-14'
end_date = '2026-04-15'
unavailabilities = self.env['account.analytic.line'].with_user(test_user).with_context(get_current_user_unavailable_dates=True).grid_unavailability(
start_date=start_date,
end_date=end_date,
groupby=''
)
self.assertIn(False, unavailabilities, "The result should contain the key False when no groupby is used.")
unavailable_dates = unavailabilities[False]
expected_dates = [date(2026, 4, 14), date(2026, 4, 15)]
for d in expected_dates:
self.assertIn(d, unavailable_dates, f"Date {d} should be marked as unavailable for this employee.")
def test_grid_unavailability_respects_employee_working_schedule(self):
""" Test that timesheet grid shows public holidays from employee's working schedule, not company default.
Test Cases:
===========
1) Create two working schedules with different public holidays
2) Set company default to one schedule, employee to another
3) Test "My Timesheets" view shows employee's holidays
"""
schedule_35h, schedule_40h = self.env['resource.calendar'].create([
{
'name': 'Schedule 35 hours/week',
'hours_per_day': 7.0,
'attendance_ids': [(0, 0, {
'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 15
})],
},
{
'name': 'Schedule 40 hours/week',
'hours_per_day': 8.0,
'attendance_ids': [(0, 0, {
'name': 'Monday Morning', 'dayofweek': '0', 'hour_from': 8, 'hour_to': 16
})],
},
])
self.env.company.resource_calendar_id = schedule_40h
employee_holiday_date = date(2025, 6, 30) # Employee's public holiday (35h schedule)
company_holiday_date = date(2025, 7, 7) # Company's public holiday (40h schedule)
self.env['resource.calendar.leaves'].create([
{
'name': 'Employee Public Holiday (35h)',
'calendar_id': schedule_35h.id,
'time_type': 'leave',
'date_from': datetime.combine(employee_holiday_date, time.min),
'date_to': datetime.combine(employee_holiday_date, time.max),
},
{
'name': 'Company Public Holiday (40h)',
'calendar_id': schedule_40h.id,
'time_type': 'leave',
'date_from': datetime.combine(company_holiday_date, time.min),
'date_to': datetime.combine(company_holiday_date, time.max),
},
])
self.empl_employee.resource_calendar_id = schedule_35h
analytic_line_model = self.env['account.analytic.line'].with_user(self.empl_employee.user_id).with_context(get_current_user_unavailable_dates=True)
my_timesheets_result = analytic_line_model.grid_unavailability('2025-06-28', '2025-07-12')
my_unavailable_days = my_timesheets_result.get(False, [])
self.assertIn(employee_holiday_date, my_unavailable_days,
"My Timesheets should show employee's assigned schedule public holiday")
self.assertNotIn(company_holiday_date, my_unavailable_days,
"My Timesheets should NOT show company default schedule holiday when employee has different schedule")