134 lines
5.9 KiB
Python
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")
|