Time off¶
The hr_holidays module (Time Off application) lets employees request time off, managers
approve it, and HR grant the time that can be taken. It is built on:
the work entry types (
hr.work.entry.type): in 20.0,hr.leave.typewas merged into them, so a time off type is a work entry type, extended byhr_holidayswith the time off configuration;the time off requests (
hr.leave): a period of absence (or of working time out of the office) of an employee, which goes through an approval flow;the allocations (
hr.leave.allocation): the time granted to an employee for a type, fixed or earned over time with accrual plans, see Time off allocations and accruals;the resource leaves (
resource.calendar.leaves): validated time off creates one, which removes the time from the working schedule, hence from the work entries and the payslips;the mandatory days (
hr.leave.mandatory.day): days on which employees cannot request time off.
This page covers the types, the requests and their effects; allocations, balances and accruals are covered in Time off allocations and accruals.
Veja também
Working schedules for the schedules and leaves the durations are computed from, Working time and calendars for the calendars of employees over time and Work entries for the work entries and the time rules.
Nota
The examples run in odoo-bin shell on a database with hr_holidays and its demo data. The
shell runs as superuser, which bypasses the approval checks: the examples first switch to the
administrator, a time off administrator, with env = env(user=env.ref('base.user_admin')).
Time off types¶
A time off type is a hr.work.entry.type with time_off_selectable set. Its work entry fields
(code, country_id, count_as, amount_rate, see Work entry types)
apply to the time off as to any work entry. hr_holidays adds:
requires_allocationWhether the time must be granted by an allocation first (e.g. paid time off), or can be taken freely (e.g. sick leave, unpaid leave). It cannot be changed once requests of the type exist.
request_unitThe granularity of the requests:
day,half_dayorhour(Custom Hours). Requests of a type by hour can also be taken by day or half day.unit_of_measureThe unit the type is allocated and counted in:
hour(default) orday. Balances are expressed in this unit.leave_validation_typeandallocation_validation_typeWho approves the requests and the allocations:
no_validation,hr(By HR Responsible, default),manager(By Time Off Approver) orboth(time off approver, then HR). See States and approval.count_days_asworking(default): the duration counts the working days of the schedule;calendar: every day counts.include_public_holidays_in_duration(Ignore Public Holidays) counts the public holidays as time off instead of deducting them.count_days_ascannot be changed once requests of the type exist,include_public_holidays_in_durationonce requests of the current year overlap a public holiday.allows_negativeandmax_allowed_negativeLet the balance go below zero, down to
-max_allowed_negative.employee_requestsWhether employees can request allocations of the type themselves.
allow_request_on_topAllow other requests to overlap the requests of this type; only for working time types.
elligible_for_accrual_rateWhether the time off counts as worked time for the accrual plans based on worked time. Always set for working time types.
create_calendar_meeting,support_document,color,hide_on_dashboard, …User interface options: a calendar event per validated request, a supporting document notice, dashboard display.
The type also has non-stored fields computed for the employee of the context (employee_id or
default_employee_id, else the user’s employee): max_leaves, leaves_taken,
virtual_remaining_leaves and has_valid_allocation. With employee_id in the context, the
display name also shows the balance.
Aviso
count_as defaults to working_time on hr.work.entry.type. An absence type must set
count_as = 'absence', otherwise its time off counts as worked time in the schedules, the
work entries and the payslips.
Example
from datetime import date
env = env(user=env.ref('base.user_admin'))
employee = env['hr.employee'].search([('name', '=', 'Ronnie Hart')])
pto, unpaid = env['hr.work.entry.type'].create([{
'name': 'Paid Time Off',
'code': 'DOCPTO',
'count_as': 'absence',
'requires_allocation': True,
'request_unit': 'half_day',
'unit_of_measure': 'day',
'leave_validation_type': 'manager',
}, {
'name': 'Unpaid Leave',
'code': 'DOCUNPAID',
'count_as': 'absence',
'amount_rate': 0.0,
'requires_allocation': False,
'request_unit': 'hour',
'leave_validation_type': 'no_validation',
}])
pto.country_id.code, pto.allocation_validation_type, pto.elligible_for_accrual_rate
# ('US', 'hr', False): the country of the company, defaults
env['hr.leave.allocation'].create({
'employee_id': employee.id,
'work_entry_type_id': pto.id,
'number_of_days': 20,
'date_from': date(2026, 1, 1),
}).action_approve()
pto.with_context(employee_id=employee.id).read(['max_leaves', 'virtual_remaining_leaves'])
# [{'id': ..., 'max_leaves': 20.0, 'virtual_remaining_leaves': 20.0}]
pto.with_context(employee_id=employee.id).display_name
# 'Paid Time Off (20 remaining out of 20 days)'
Time off requests¶
A request (hr.leave) belongs to an employee (employee_id) and has a type
(work_entry_type_id). Its period is entered with the request fields, and computed into
date_from and date_to:
request_date_from,request_date_toThe first and last days (
date), in the employee’s timezone.request_date_from_period,request_date_to_periodamorpm, for types by half day: a request from Monday afternoon to Wednesday morning is('pm', 'am').request_hour_from,request_hour_toFloat hours (
13.5is 13:30) in the employee’s timezone, for types by hour. When both are0, the hours of the schedule are used.date_from,date_toNaive UTC datetimes, computed by
_compute_date_from_to(). A day starts at the first working hour and ends at the last working hour of the schedule of the employee’s version on that day (a day off takes the hours of the nearest working day, see_get_hours_for_date()); a half day starts or ends at noon. Never write them: write the request fields.resource_calendar_idThe working schedule of the version in contract during the request, computed. A request cannot span versions with different schedules (
_check_contracts()).number_of_days,number_of_hoursThe duration, computed, see Durations.
request_duration (full, am, pm, specific) and request_date_hour_from /
request_date_hour_to are form and calendar view helpers, converted from and to the request
fields.
Example
Paid time off from Monday to Wednesday morning, created by the administrator for another employee, and an unpaid leave of two hours and a half:
leave = env['hr.leave'].create({
'employee_id': employee.id,
'work_entry_type_id': pto.id,
'request_date_from': date(2026, 11, 16),
'request_date_to': date(2026, 11, 18),
'request_date_to_period': 'am',
})
leave.date_from, leave.date_to, leave.tz
# (datetime.datetime(2026, 11, 16, 7, 0), datetime.datetime(2026, 11, 18, 11, 0),
# 'Europe/Brussels'): 8:00 to 12:00 local time
leave.number_of_days, leave.number_of_hours, leave.state
# (2.5, 20.0, 'validate')
leave.display_name
# 'Ronnie Hart on Paid Time Off: 2.5 days (11/16/2026 to 11/18/2026)'
hourly = env['hr.leave'].create({
'employee_id': employee.id,
'work_entry_type_id': unpaid.id,
'request_date_from': date(2026, 11, 20),
'request_date_to': date(2026, 11, 20),
'request_hour_from': 13.5,
'request_hour_to': 16.0,
})
hourly.date_from, hourly.date_to, hourly.number_of_days, hourly.number_of_hours
# (datetime.datetime(2026, 11, 20, 12, 30), datetime.datetime(2026, 11, 20, 15, 0),
# 0.313, 2.5)
The paid time off is approved at once: see States and approval.
Durations¶
number_of_days and number_of_hours are computed by _get_durations(),
which can also be called directly (it returns {leave.id: (days, hours)} without assigning the
fields). The hours are the working hours of the request’s schedule between date_from and
date_to, for the employee (see The resource mixin), minus the
absence leaves: public holidays and other validated absences of the employee, but not the
request itself. Then:
types by day round the days up to whole days, types by half day to half days;
_get_durations()withcheck_work_entry_type=Falsegives the real number of working days;with
count_days_as = 'calendar', every day of the period counts (public holidays still deducted, unlessinclude_public_holidays_in_duration), at the hours per day of the schedule;with
include_public_holidays_in_duration, public holidays are not deducted;a single day request of an employee with a flexible schedule counts the real length of the request (minus public holidays), the hours of a flexible schedule having no position in the day;
working time types outside the schedule (e.g. a business trip on a Saturday) count their days, or their clock hours for types by hour.
The days of a request by hour are its hours divided by the hours of a day of the schedule.
Example
One week, Monday to Sunday, with a public holiday on Tuesday:
from datetime import datetime
day_type, half_type, hour_type = env['hr.work.entry.type'].create([{
'name': f'Leave by {unit}',
'code': f'DOC{unit.upper()}',
'count_as': 'absence',
'requires_allocation': False,
'request_unit': unit,
'leave_validation_type': 'no_validation',
} for unit in ('day', 'half_day', 'hour')])
env['resource.calendar.leaves'].create({
'name': 'Founders Day', # no resource: a public holiday
'date_from': datetime(2026, 12, 8, 7, 0),
'date_to': datetime(2026, 12, 8, 15, 0),
'company_id': employee.company_id.id,
})
week = env['hr.leave'].create({
'employee_id': employee.id,
'work_entry_type_id': day_type.id,
'request_date_from': date(2026, 12, 7),
'request_date_to': date(2026, 12, 13),
})
week.number_of_days, week.number_of_hours # (4.0, 32.0)
ph_counted, calendar_days = env['hr.work.entry.type'].create([{
'name': 'PH counted', 'code': 'DOCPH', 'count_as': 'absence',
'requires_allocation': False, 'include_public_holidays_in_duration': True,
}, {
'name': 'Calendar days', 'code': 'DOCCAL', 'count_as': 'absence',
'requires_allocation': False, 'count_days_as': 'calendar',
}])
for leave_type in (ph_counted, calendar_days):
probe = env['hr.leave'].new({
'employee_id': employee.id,
'work_entry_type_id': leave_type.id,
'request_date_from': date(2026, 12, 7),
'request_date_to': date(2026, 12, 13),
})
print(leave_type.name, probe.number_of_days, probe.number_of_hours)
# PH counted 5.0 40.0
# Calendar days 6.0 48.0
The same afternoon requested with each unit (the hours are ignored by the types by day and half day, the periods by the type by hour):
for leave_type in (day_type, half_type, hour_type):
probe = env['hr.leave'].new({
'employee_id': employee.id,
'work_entry_type_id': leave_type.id,
'request_date_from': date(2026, 12, 15),
'request_date_to': date(2026, 12, 15),
'request_date_from_period': 'pm',
'request_date_to_period': 'pm',
'request_hour_from': 9.0,
'request_hour_to': 11.0,
})
print(leave_type.request_unit, probe.date_from, probe.date_to,
probe.number_of_days, probe.number_of_hours)
# day 2026-12-15 07:00:00 2026-12-15 15:00:00 1.0 8.0
# half_day 2026-12-15 11:00:00 2026-12-15 15:00:00 0.5 4.0
# hour 2026-12-15 08:00:00 2026-12-15 10:00:00 0.25 2.0
States and approval¶
![digraph leave_states {
rankdir=LR;
node [shape=box, style=rounded, fontname="sans-serif", fontsize=10];
edge [fontname="sans-serif", fontsize=9];
confirm [label="confirm\n(To Approve)"];
validate1 [label="validate1\n(Second Approval)"];
validate [label="validate\n(Approved)"];
refuse [label="refuse\n(Refused)"];
cancel [label="cancel\n(Cancelled)"];
confirm -> validate1 [label="first approval\n(type 'both')"];
confirm -> validate [label="action_approve"];
validate1 -> validate [label="action_approve"];
confirm -> refuse [label="action_refuse"];
validate1 -> refuse;
validate -> refuse;
validate -> confirm [label="action_back_to_approval"];
validate -> cancel [label="_action_user_cancel"];
}](../../../../_images/graphviz-b36579a001a0a927b642af167280fde512358258.png)
A request is created in confirm. The validation type of its type decides who approves it:
no_validationThe request is approved on creation.
hrA time off officer (
hr_holidays.group_hr_holidays_user) approves it.managerThe employee’s time off approver (
hr.employee.leave_manager_id, Time Off Approver, defaulting to the manager’s user) approves it, or an officer.bothThe time off approver gives a first approval (
validate1), then an officer approves it.
On creation, _process_auto_approve_activities() approves the request
right away when its type has no validation or when an officer creates it for another
employee; otherwise, it schedules an approval activity for
_get_responsible_for_approval(): the time off approver (or the manager’s
user, or the HR responsible) for manager and the first step of both, the employee’s HR
responsible (hr_responsible_id) for hr and the second step of both.
The actions are:
action_approve()Validates the request if the user can (
_action_validate()), else gives the first approval of abothtype. Officers validate in one step, whatever the type. Withcheck_state=False, rights are not checked.action_refuse()Refuses a request to approve or approved.
action_back_to_approval()Resets approved requests to
confirm._action_user_cancel()and_force_cancel()Cancel a request, the first one checking that the user can (an employee can cancel their own requests unless they started). The Cancel button opens the
hr.holidays.cancel.leavewizard, which calls the first one with a reason.
What the current user may do is given by _get_next_states_by_state()
({state: set(next_states)}) and checked by _check_approval_update(),
which writing state also calls. The fields can_approve, can_validate, can_refuse,
can_cancel and can_back_to_approve expose it to the views. The superuser bypasses these
checks.
Example
Marc Demo (user base.user_demo) requests time off; his time off approver is the
administrator:
demo = env.ref('base.user_demo')
marc = demo.employee_id
marc.leave_manager_id.name # 'Mitchell Admin'
vacation = env['hr.work.entry.type'].create({
'name': 'Vacation',
'code': 'DOCVAC',
'count_as': 'absence',
'requires_allocation': False,
'leave_validation_type': 'manager',
})
leave = env['hr.leave'].with_user(demo).create({
'employee_id': marc.id,
'work_entry_type_id': vacation.id,
'request_date_from': date(2026, 12, 7),
'request_date_to': date(2026, 12, 8),
})
leave.state # 'confirm'
leave.activity_ids.mapped(lambda a: (a.activity_type_id.name, a.user_id.name))
# [('Time Off Approval', 'Mitchell Admin')]
leave._get_next_states_by_state()['confirm'] # set(): Marc cannot approve it
leave.with_user(env.user).action_approve()
leave.state, leave.first_approver_id.name # ('validate', 'Mitchell Admin')
With a type validated twice, Marc approves the request of Randall Lewis, whose time off approver he is, then the administrator validates it:
vacation.leave_validation_type = 'both'
randall = env['hr.employee'].search([('name', '=', 'Randall Lewis')])
leave = env['hr.leave'].with_user(demo).create({
'employee_id': randall.id,
'work_entry_type_id': vacation.id,
'request_date_from': date(2026, 12, 9),
'request_date_to': date(2026, 12, 9),
})
leave.action_approve()
leave.state, leave.first_approver_id.name # ('validate1', 'Marc Demo')
leave.with_user(env.user).action_approve()
leave.state, leave.second_approver_id.name # ('validate', 'Mitchell Admin')
hr_holidays defines the groups Employee (group_hr_holidays_employee, every internal
user), Time Off Responsible (group_hr_holidays_responsible, given automatically to the users
set as time off approvers), Officer: Manage all requests (group_hr_holidays_user) and
Administrator (group_hr_holidays_manager). Users who are not officers only access their
own requests and the requests of the employees they approve; officers access all the requests
of their companies. The description of a request (name, stored in private_name) is only
readable by officers, the employee and their time off approver.
Checks¶
Creating or changing a request checks that:
it does not overlap another request of the employee with the same
count_as, unless one of their types hasallow_request_on_top(_check_date, skipped with the context keyleave_skip_date_check);it is covered by the allocations of the employee when the type requires one (
_check_validity(), see Balances);it is not on a mandatory day, for users who are not officers (same method);
an approved request is not moved without being reset first (
_check_date_state);an absence by hour does not exceed the planned hours of its days (
_get_max_allowed_absence_hours());it does not span versions with different schedules (
_check_contracts()).
Validating an absence of zero hours, e.g. on a public holiday, raises a ValidationError
(The following employees are not supposed to work during that period), except for a few sick
and work accident types (_get_leaves_on_public_holiday()).
Resource leaves¶
Validation (_validate_leave_request()) creates a
resource.calendar.leaves record per request
(_create_resource_leave()), from
_prepare_resource_leave_vals(): the employee’s resource, the request’s
schedule, date_from and date_to, the type (work_entry_type_id, count_as,
elligible_for_accrual_rate) and the request itself (holiday_id). This leave is what the rest
of Odoo sees: the work intervals of the employee (see Working schedules),
the planning and Gantt views, the work entries and the payslips.
It follows the request: leaving the validate state (refusal, reset, cancellation, deletion)
removes it (_remove_resource_leave()), and changing the dates or the
type of a validated request rewrites it (_amend_resource_leave_dates()).
Validation also creates a calendar event (meeting_id) when the type has
create_calendar_meeting.
Example
leave = env['hr.leave'].search([('employee_id', '=', marc.id), ('state', '=', 'validate'),
('work_entry_type_id', '=', vacation.id)])
env['resource.calendar.leaves'].search([('holiday_id', '=', leave.id)]).read(
['resource_id', 'calendar_id', 'date_from', 'date_to', 'work_entry_type_id',
'count_as'])
# [{'id': ..., 'resource_id': (3, 'Marc Demo'), 'calendar_id': (1, '40 hours/week'),
# 'date_from': datetime.datetime(2026, 12, 7, 7, 0),
# 'date_to': datetime.datetime(2026, 12, 8, 15, 0),
# 'work_entry_type_id': (..., 'Vacation'), 'count_as': 'absence'}]
leave.action_refuse()
leave.state # 'refuse'
env['resource.calendar.leaves'].search_count([('holiday_id', '=', leave.id)]) # 0
Public holidays¶
Public holidays are global leaves: resource.calendar.leaves without resource_id, for a
company and optionally a calendar (see Leaves). Two
public holidays of the same company and calendar cannot overlap. hr_holidays:
deducts them from the duration of the requests, unless the type has
include_public_holidays_in_duration;recomputes the requests overlapping a public holiday when it is created, changed or deleted (
_reevaluate_leaves()): their duration changes, the employee is notified, and a request no longer covered by its allocations is refused;creates the public holidays of the next year from the CSV files of
hr_holidays/data/public_holidays/, with a monthly cron (_cron_generate_public_holidays()) and the Load Public Holidays wizard (which gives them the type of code006.00).
In the work entries, a public holiday wins over a time off on the same day, unless the type
code of the time off is listed by _get_bypassing_work_entry_type_codes (see
Computing the raw values).
Example
Continuing the previous examples, a request on the public holiday only, then a second public holiday during the week of time off of the durations example:
env['hr.leave'].create({
'employee_id': marc.id,
'work_entry_type_id': day_type.id,
'request_date_from': date(2026, 12, 8),
'request_date_to': date(2026, 12, 8),
})
# ValidationError: The following employees are not supposed to work during that period:
# Marc Demo
env['resource.calendar.leaves'].create({
'name': 'Extra day',
'date_from': datetime(2026, 12, 10, 7, 0),
'date_to': datetime(2026, 12, 10, 15, 0),
'company_id': employee.company_id.id,
})
week.number_of_days, week.state # (3.0, 'validate')
Mandatory days¶
A mandatory day (hr.leave.mandatory.day) is a period (start_date to end_date) during which
employees must work, e.g. an inventory. It applies to the employees of its company_id, and can
be restricted to a working schedule (resource_calendar_id), job positions (job_ids) and
departments (department_ids, sub-departments included).
_get_mandatory_days() returns the ones applying to an employee.
Users who are not time off officers cannot create requests overlapping a mandatory day; officers
can, and the request’s has_mandatory_day is then set. The calendar views show them with
get_special_days_data().
Example
env['hr.leave.mandatory.day'].create({
'name': 'Year-end inventory',
'start_date': date(2026, 12, 17),
'end_date': date(2026, 12, 18),
'color': 2,
})
marc._get_mandatory_days(date(2026, 12, 1), date(2026, 12, 31)).mapped('name')
# ['Year-end inventory']
marc.get_mandatory_days(date(2026, 12, 1), date(2026, 12, 31))
# {'2026-12-17': 2, '2026-12-18': 2}
vals = {
'employee_id': marc.id,
'work_entry_type_id': vacation.id,
'request_date_from': date(2026, 12, 18),
'request_date_to': date(2026, 12, 18),
}
env['hr.leave'].with_user(demo).create(vals)
# ValidationError: You are not allowed to request time off on a Mandatory Day.
env['hr.leave'].create(vals).has_mandatory_day # True
Work entries and payroll¶
Validated time off reaches the work entries through its resource leave (see
Computing the raw values). hr_holidays extends hr.version
(HrVersion) so that:
the type of a leave interval is the type of its time off (
_get_leave_work_entry_type()), and overlapping leaves are arbitrated by_get_interval_leave_work_entry_type(): bypassing types first, then public holidays, then time off;the values carry the time off in
leave_ids;the duration of time off not requested by hour is the planned hours of the schedule (
_generate_work_entries_postprocess_adapt_to_calendar()): a day of time off counts as a working day, whatever the request’s hours;the leaves of the employee’s time off are found whatever their calendar (
_get_sub_leave_domain()).
The count_as and type used are the ones stored on the resource leave, copied at
validation; the paid rate comes from amount_rate. Payroll then turns the work entries into
worked days by type code.
Example
The week of the durations example (two public holidays):
vals_list = employee.version_id.generate_work_entries(date(2026, 12, 7), date(2026, 12, 11))
sorted((vals['date'].isoformat(), vals['work_entry_type_id'].code, vals['duration'],
vals.get('leave_ids')) for vals in vals_list)
# [('2026-12-07', 'DOCDAY', 8.0, hr.leave(...)), ('2026-12-08', '006.00', 8.0, None),
# ('2026-12-09', 'DOCDAY', 8.0, hr.leave(...)), ('2026-12-10', '006.00', 8.0, None),
# ('2026-12-11', 'DOCDAY', 8.0, hr.leave(...))]
Time rules. hr.leave is a time rule source (hr.time.rule.source.mixin, see
Time rule sources): when a validated request is created
or changed, the rules whose condition_work_entry_type_ids include its type reclassify the time
beyond (or missing from) their threshold. The outputs are validated requests linked to their
source (source_leave_id, output_leave_ids, time_rule_id); a source cut by a rule is
flagged is_time_rule_trimmed. Absences are clipped to the schedule before being measured
(_get_pipeline_intervals_local()). Rules can also credit the excess to
an allocation, see Allocations from time rules.
_get_generated_leave_domain() matches the requests created by rules.
Versions, departures and splits¶
Requests follow the contract of the employee:
creating or changing a version (contract dates,
date_version,resource_calendar_id) gives the requests the schedule of their version and recomputes them; a request now spanning versions with different schedules is split into one request per version, the last part being to approve again (_populate_all_new_leave_vals_from_split_leave()); approved requests starting before a new contract and overlapping it are refused;registering a departure (
hr.employee.departure.action_register) cuts the requests at the departure date, cancels the approved ones after it, deletes the others (or refuses them, see_check_refuse_future_leaves_condition()) and ends or deletes the allocations (_cleanup_employee_departure_leaves()).
Two helpers split requests:
_split_leaves()Removes a period from the requests, keeping the parts before and after it; returns the created requests.
_create_leaves_from_split()Splits a request into consecutive requests of other types, e.g. a sick leave paid by the employer for its first days then by the social security; localizations compute the split and
_get_work_entry_type_change_warning()describes it.
Pitfalls¶
Write the request fields (
request_date_from,request_hour_from, …), neverdate_fromanddate_to: they are recomputed from the request fields.An officer creating a request for another employee approves it, with all its effects (resource leave, work entries, time rules); create it in
confirmwith another user, or reset it withaction_back_to_approval().Approved requests must be reset to
confirmbefore their dates change.The shell runs as superuser: rights and transitions are not checked. Test approval flows with
with_user().A failed
createin atryblock may leave partial data in the transaction (e.g. the first part of a batch): useenv.cr.savepoint().max_leavesandvirtual_remaining_leaveson types depend on the employee in the context; without it, they are computed for the current user’s employee.The resource leave keeps the
count_asof the type at validation: changing the type’scount_asdoes not change approved requests.
Extending¶
- Resource leave
_prepare_resource_leave_vals()to add values to the resource leave.- Approval
_get_next_states_by_state(),_check_approval_update()and_get_responsible_for_approval().- Durations
_get_durations()(called by the compute, and by the forms),_get_max_allowed_absence_hours()for the maximum hours of an absence.- Splits and departures
_get_extra_default_leave_values_for_split(),_check_refuse_future_leaves_condition().- Work entries
The
hr.versionhooks of Extending, e.g._get_leave_work_entry_type_datesto change the type of a long absence after some days.
Reference¶
Original definition from hr_holidays¶
- model odoo.addons.hr_holidays.models.hr_leave.HrLeave[código fonte]¶
- _name = hr.leave¶
Time off request of an employee.
The request goes through the states
confirm,validate1(first approval of the types validated twice),validate,refuseandcancel; the transitions the current user may perform are given by_get_next_states_by_state()and checked by_check_approval_update(). The description (name, stored inprivate_name) is only readable by time off officers, the employee and their time off approver. Users who are not officers only access their own requests and the requests of the employees they approve, and a multi-company rule applies to everyone.- state: str¶
- Name
Status
- Selection
confirm: To Approverefuse: Refusedvalidate1: Second Approvalvalidate: Approvedcancel: Cancelled- Default
confirm
- request_date_from: datetime.date¶
- Name
Request Start Date
- request_date_to: datetime.date¶
- Name
Request End Date
- request_date_from_period: str¶
- Name
Date Period Start
- Selection
am: Morningpm: Afternoon- Default
am
- date_from: datetime.datetime¶
- Name
Start Date
- Readonly
this field is not supposed to/cannot be set manually
- date_to: datetime.datetime¶
- Name
End Date
- Readonly
this field is not supposed to/cannot be set manually
- number_of_days: float¶
- Name
Duration (Days)
- Readonly
this field is not supposed to/cannot be set manually
Number of days of the time off request. Used in the calculation.
- number_of_hours: float¶
- Name
Duration (Hours)
Number of hours of the time off request. Used in the calculation.
- first_approver_id: int¶
- Name
First Approval
- Readonly
this field is not supposed to/cannot be set manually
- Comodel
This area is automatically filled by the user who validate the time off
- second_approver_id: int¶
- Name
Second Approval
- Readonly
this field is not supposed to/cannot be set manually
- Comodel
This area is automatically filled by the user who validate the time off with second level (If time type need second validation)
- has_mandatory_day: bool¶
- Name
Has Mandatory Day
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
- output_leave_ids: Sequence[odoo.orm.commands.Command]¶
- Name
Output Leave
- Comodel
- is_time_rule_trimmed: bool¶
- Name
Trimmed by Time Rule
- Default
False
Set when a time rule trims this leave’s end to sub-day precision. Prevents _compute_date_from_to from snapping the end back to the schedule boundary.
- create(vals_list)[código fonte]¶
Create time off requests, check them and start their approval.
Requests whose type is selectable are checked with
_check_validity()(unless the context hasskip_check_validity). Each request is then auto-approved or gets approval activities (_process_auto_approve_activities()) and the time rules run on it. With the context keyleave_fast_create, the double validation rights, the approval and the time rules are skipped, and the validated requests directly get their resource leave.
- write(vals)[código fonte]¶
Write on time off requests, keeping their resource leave in sync.
Changing the state checks
_check_approval_update(). Leaving the'validate'state removes the resource leave and reverses the time rule allocation credits; changing the dates or the type of a validated request amends its resource leave (_amend_resource_leave_dates()). Users who are not officers cannot modify started or cancelled requests.
- unlink()[código fonte]¶
Delete requests, after reversing their time rule credits and removing their leaves.
- _compute_date_from_to()[código fonte]¶
Compute
date_fromanddate_to(naive UTC) from the request fields.The bounds are taken in the employee’s timezone: requests in hours use
request_hour_from/request_hour_to(or the hours of the schedule when both are0), half days the hours of the morning or afternoon, days the first and last working hours of the first and last days (see_get_hour_from_to()). Time rule outputs and trimmed sources keep the dates written by the time rules.
- _get_hour_from_to(request_date_from, request_date_to, day_period=None, count_non_working_days=False)[código fonte]¶
Return the local hours a request starts and ends at.
The start is the first hour of the schedule of the employee on
request_date_from, the end the last hour onrequest_date_to, see_get_hours_for_date(). Working time types in hours keep their explicit hours, or last the planned hours of the day from its start.- Parâmetros
request_date_from (datetime.date) – first day
request_date_to (datetime.date) – last day
day_period (str) –
'morning'or'afternoon'for a half daycount_non_working_days (bool) – count the days off as working days, centered on noon
- Retorna
(hour_from, hour_to)as float hours- Tipo de retorno
- _to_utc(date, hour, resource)[código fonte]¶
Return the naive UTC datetime of
hourondatein the resource’s timezone.- Parâmetros
date (datetime.date) – local day
hour (float) – local hour, capped at 24
resource – record with a
tzfield (employee); the user’s timezone without it
- Tipo de retorno
- _get_durations(check_work_entry_type=True, resource_calendar=None, additional_domain=None)[código fonte]¶
Compute the duration of the requests without assigning the fields.
Factored out of
_compute_durationso it can be called or overridden without triggering the computes depending onnumber_of_days/number_of_hours. The hours are the working hours of the schedule within[date_from, date_to], minus the absence leaves: public holidays (unless the type hasinclude_public_holidays_in_duration) and the other validated absences of the employee, but not the leave itself nor its time rule source. Then:types counted in calendar days (
count_days_as = 'calendar') count every day;a flexible schedule counts the real length of a single-day request;
types requested by day are rounded up to whole days, half days to half days;
working time types outside the schedule count the days, or the clock hours.
- Parâmetros
check_work_entry_type (bool) –
Falseto skip the rounding to whole days of the types requested by day (gives the real number of working days)resource_calendar –
resource.calendarto use instead ofresource_calendar_idadditional_domain – domain added to the one of the deducted leaves
- Retorna
{leave.id: (number_of_days, number_of_hours)},(0, 0)for requests without dates- Tipo de retorno
- _plans_hours_on_the_clock(worked_hours)[código fonte]¶
Tell whether the duration in hours of the request is clock time.
True for working time types requested in hours when the request is on a single day or covers no working time: the end is then
date_fromplus the duration, not planned on the schedule.
- _inverse_number_of_hours()[código fonte]¶
Move the end of the requests to give them the
number_of_hoursset.Only for requests to approve: the end is planned on the version’s schedule from
date_from(or on the clock, see_plans_hours_on_the_clock()) and written onrequest_date_to/request_hour_to.- Levanta
ValidationError – if the hours do not fit in the working time of the request days
- _subtract_public_holidays(public_holidays)[código fonte]¶
Return the clock hours of the request minus the given public holidays.
- Parâmetros
public_holidays – global
resource.calendar.leaves- Tipo de retorno
- _get_allowed_request_durations()[código fonte]¶
Return the values of
request_durationthe request can use.['full']for requests over several days and types requested by day,['full', 'am', 'pm']for half days, plus'specific'for types requested in hours.
- _get_request_duration(date_from, period_from, date_to, period_to)[código fonte]¶
Return the
request_durationof a request given its bounds.- Retorna
period_from('am'or'pm') for a lone half day,'full'otherwise- Tipo de retorno
- _get_request_date_hours(reader_tz)[código fonte]¶
Return the bounds a calendar view draws the request on.
Requests in hours return their
date_from/date_towith the wall clock of the request’s timezone restamped inreader_tz(8:00 in Tokyo is drawn at 8:00 in Brussels). Days and half days return midnight or noon of their first and last days inreader_tz, so that moving them by half a day is moving them by one period.- Parâmetros
reader_tz (zoneinfo.ZoneInfo) – timezone of the reader, see
_reader_tz()- Retorna
(start, stop)naive UTC datetimes,(False, False)without request dates- Tipo de retorno
- _get_request_vals_from_date_hours(date_hour_from, date_hour_to)[código fonte]¶
Return the request values matching bounds drawn by a calendar view.
Reverse of
_get_request_date_hours(); the stop is exclusive, so 00:00 on D+1 ends the afternoon of D. An empty bound keeps its current value.- Parâmetros
date_hour_from (datetime) – new start, naive UTC
date_hour_to (datetime) – new end, naive UTC
- Retorna
values to write (request dates, periods, hours,
request_duration),{}when the bounds are invalid or unchanged- Tipo de retorno
- _reader_tz()[código fonte]¶
Return the timezone the request is read in, the one the web client draws it on.
- Tipo de retorno
- reschedule_from_calendar(date_from, date_to)[código fonte]¶
Move a request to the bounds a calendar view displays.
Converts
date_from/date_towith_get_request_vals_from_date_hours()and writes the request fields. An approved request needing validation goes back to'confirm'.- Parâmetros
date_from – new start, as displayed (
request_date_hour_from)date_to – new end, as displayed (
request_date_hour_to)
- _check_validity()[código fonte]¶
Check that the requests are covered by allocations and avoid mandatory days.
For the types requiring an allocation (unless the context has
skip_allocation_check), the balance of the employee on the first day of the request must cover it, withinmax_allowed_negativewhen the type allows a negative balance (seehr.work.entry.type.get_allocation_data()). Users who are not time off officers cannot request time off on a mandatory day.With the context key
multi_leave_request, the employees without enough allocation are returned instead of raising (used to create time off for several employees at once).- Retorna
(employees_without_allocation, zero_duration_employees), the second being the employees with an absence of zero hours (only withmulti_leave_request)- Tipo de retorno
- Levanta
ValidationError – when a request is not covered
- _get_allocation_balance(target_date)[código fonte]¶
Return the balance of the allocations each request can use on
target_date.Counts the allocations not expired on
target_date, based on_get_consumed_leaves().- Parâmetros
target_date (datetime.date) – date of the balance
- Retorna
{leave: (virtual_remaining_leaves, max_leaves)}, in the unit of the type (unit_of_measure)- Tipo de retorno
- _check_contracts()[código fonte]¶
Forbid a time off over several versions with different working schedules.
A time off can still end up across such versions when the versions are changed after its creation (
hr.versionthen splits it, seehr_holidays’shr.version). Skipped with the context keyskip_leave_version_checkand for time rule outputs.
- _get_overlapping_contracts()[código fonte]¶
Return the versions in contract of the employee overlapping the request dates.
- Tipo de retorno
hr.version
- _get_max_allowed_absence_hours(base_max_hours)[código fonte]¶
Hook returning the maximum number of hours of an absence requested in hours.
_check_max_absence_per_daypasses the planned hours of the request days (24 per day for flexible schedules); localizations can raise or lower it.
- _check_double_validation_rules(employees, state)[código fonte]¶
Check the rights to approve requests of a type validated twice (
'both').Time off administrators may do everything. Otherwise, a first approval (
'validate1') requires being the time off approver of the employees or a time off officer, and the second one ('validate') being a time off officer.- Parâmetros
employees –
hr.employeeof the requestsstate (str) – target state
- Levanta
AccessError – when not allowed
- _process_auto_approve_activities()[código fonte]¶
Approve a new request automatically, or notify its approvers.
The request is approved (as superuser) when its type needs no validation, or when it is created by a time off officer for another employee. Otherwise, approval activities are scheduled for
_get_responsible_for_approval().
- action_approve(check_state=True)[código fonte]¶
Approve the requests.
A request goes to
'validate'(see_action_validate()) when the user can validate it, otherwise to'validate1'(first approval of a type validated twice) when the user can approve it. Time off officers can validate in one step.
- _action_validate(check_state=True)[código fonte]¶
Validate the requests (state
'validate').Sets the approvers, creates the resource leaves and meetings (
_validate_leave_request()), closes the activities and runs the time rules.- Parâmetros
check_state (bool) – check that the user can validate the requests
- Levanta
UserError – when the user cannot validate a request
ValidationError – when an absence covers no working time, see
_get_leaves_on_public_holiday()
- action_refuse()[código fonte]¶
Refuse requests to approve or approved: the resource leaves and meetings are removed.
- Levanta
UserError – when a request is not
'confirm','validate1'or'validate'
- action_back_to_approval()[código fonte]¶
Reset to
'confirm'the requests the user may reset; others are ignored.
- _move_validate_leave_to_confirm()[código fonte]¶
Reset the requests to
'confirm', removing their meetings and resource leaves.
- _action_user_cancel(reason=None)[código fonte]¶
Cancel a request on behalf of its employee, see
_force_cancel().- Parâmetros
reason (str) – reason posted on the request
- Levanta
ValidationError – when the user cannot cancel the request (
can_cancel)
- _force_cancel(reason=None, msg_subtype='mail.mt_comment', notify_responsibles=True)[código fonte]¶
Cancel the requests without checking the rights.
The state becomes
'cancel', the meetings and resource leaves are removed. With a reason, it is posted on each request and the approvers who already approved it are notified.
- _post_leave_cancel()[código fonte]¶
Archive the meetings and remove the resource leaves of the requests.
- _prepare_leave_unlink()[código fonte]¶
Undo the effects of the requests before their deletion.
Reverses the time rule allocation credits, archives the meetings and removes the resource leaves.
- _get_next_states_by_state()[código fonte]¶
Return the states the current user can move the request to, from each state.
Officers can move between all states (and to
'validate1'for types validated twice), time off approvers of the employee can approve and refuse depending on the validation type, and employees can cancel their own requests, unless started.- Retorna
{state: set(next_states)}- Tipo de retorno
- _check_approval_update(state, raise_if_not_possible=True)[código fonte]¶
Check that the current user can move the requests to
state.Based on
_get_next_states_by_state(); the superuser can do everything.
- _get_responsible_for_approval()[código fonte]¶
Return the user who must approve the request in its current state.
For the approval by the time off approver (
'manager', or'both'in'confirm'): the employee’sleave_manager_id, else the manager’s user, else the HR responsible. For the approval by HR ('hr', or'both'in'validate1'): the employee’shr_responsible_id.- Tipo de retorno
res.users
- activity_update()[código fonte]¶
Schedule or close the approval activities according to the state of the requests.
- _notify_leave_request()[código fonte]¶
Notify the approvers (
_get_responsible_for_approval()) of new requests.
- _notify_manager()[código fonte]¶
Notify the time off approver of the employee when a request it approved is refused.
- _notify_change(message, subtype_xmlid='mail.mt_note')[código fonte]¶
Post
messageon the requests and notify their employee.
- _get_leaves_on_public_holiday()[código fonte]¶
Return the absences of zero duration, which cannot be validated.
Such a request covers no working time (e.g. a public holiday). Some types (sick leave, maternity, work accident codes) are accepted anyway.
- Tipo de retorno
hr.leave
- _validate_leave_request()[código fonte]¶
Apply the effects of the validation of the requests.
Creates the resource leaves (
_create_resource_leave()), the calendar events when the type hascreate_calendar_meeting, and posts a message to the employee.
- _prepare_resource_leave_vals()[código fonte]¶
Return the values of the
resource.calendar.leavesof a validated request.Hook to add values. The leave copies the type (
work_entry_type_id,count_as,elligible_for_accrual_rate), the dates and the calendar of the request, and is linked to the employee’s resource and to the request (holiday_id).- Tipo de retorno
- _create_resource_leave()[código fonte]¶
Create the
resource.calendar.leavesof the requests, replacing existing ones.Requests with an empty span get none. Called on validation.
- Retorna
the created leaves
- Tipo de retorno
resource.calendar.leaves
- _remove_resource_leave()[código fonte]¶
Delete the
resource.calendar.leavesof the requests (on refusal, cancellation, …).
- _amend_resource_leave_dates()[código fonte]¶
Update the resource leaves of validated requests whose dates or type changed.
Rewrites them with
_prepare_resource_leave_vals(); requests without resource leave are ignored.
- _split_leaves(split_date_from, split_date_to=False)[código fonte]¶
Cut the requests out of a period, keeping the parts before and after it.
[request_date_from, request_date_to]becomes[request_date_from, split_date_from - 1 day]and[split_date_to, request_date_to]; parts without working time are dropped. The request keeps the first part (or the only one), a copy in the same state is created for the other one. Used when an employee leaves the company.- Parâmetros
split_date_from (datetime.date) – first day removed
split_date_to (datetime.date) – first day kept after the cut; defaults to
split_date_from, which cuts the request in two without removing anything
- Retorna
the created requests
- Tipo de retorno
hr.leave
- _get_split_hour_vals(date_from=None, date_to=None)[código fonte]¶
Return the hours of a part of a request in hours cut by
_split_leaves().The part whose first (or last) day changes takes the first (or last) hour of the schedule on that day.
- Tipo de retorno
- _create_leaves_from_split(leave_split, use_worked_days=False)[código fonte]¶
Split the request into consecutive requests of the given types and durations.
Used by localizations to switch the type of a long absence (e.g. a sick leave paid by the employer, then by the social security). With a single entry, only the type of the request changes.
- _get_extra_default_leave_values_for_split()[código fonte]¶
Hook returning extra values for the requests created when splitting.
See
_create_leaves_from_split().- Tipo de retorno
- _get_work_entry_type_change_warning(leave_split)[código fonte]¶
Return the message warning that the request will be split or change type.
- Parâmetros
leave_split (list) – see
_create_leaves_from_split()- Tipo de retorno
- _get_request_date_to(number_of_days, days_data)[código fonte]¶
Return the day at which
number_of_daysworking days are reached, from the start.
- _get_request_date_to_with_period(number_of_days, work_intervals)[código fonte]¶
Return the day and the period at which
number_of_daysworking days are reached.- Parâmetros
number_of_days (float) – number of working days, possibly with a half day
work_intervals – work intervals of the request
- Retorna
(date, 'am' or 'pm'),Falseif not reached
- _get_calendar_days(date_min=datetime.date(1, 1, 1), date_max=datetime.date(9999, 12, 31))[código fonte]¶
Return the number of calendar days of the request within
[date_min, date_max].Half days are counted as 0.5.
- Tipo de retorno
- _get_calendar_days_between_leaves(leave_from, leave_to)[código fonte]¶
Return the number of calendar days between two requests.
The days strictly between the end of
leave_fromand the start ofleave_to.Half days are counted as 0.5.
- Parâmetros
leave_from – the first
hr.leaveleave_to – the second
hr.leave
- Tipo de retorno
- _cancel_invalid_leaves()[código fonte]¶
Cron: cancel the requests of the next 31 days that accruals will not cover.
Only types with an accrual allocation are checked: a request whose balance on its start date exceeds the allowed negative amount is cancelled.
- get_unusual_days(date_from, date_to=None)[código fonte]¶
Return the unusual days of the employee of the context (or of the user).
See
_get_unusual_days().- Retorna
{'YYYY-MM-DD': bool}- Tipo de retorno
- _get_generated_leave_domain()[código fonte]¶
Return the domain of the leaves generated by time rules (outputs and remainders).
- Tipo de retorno
odoo.fields.Domain
- _get_search_request_date_hour_from_to_domain(date_field, hour_field, operator, value)[código fonte]¶
Search
request_date_hour_from/request_date_hour_toon the stored request fields.Mirrors
_get_request_date_hours(): the day is compared ondate_field, the hour onhour_fieldfor requests in hours, on the period for half days.
- _apply_record_output(rules, excess, deficit, active_iv=None)[código fonte]¶
Apply the result of the time rules on the requests.
- _get_pipeline_intervals_local(schedule)[código fonte]¶
Return the parts of the request that the time rules consider.
Absences are clipped to the schedule: nights, breaks and days off within the request do not count toward the thresholds. Other types keep their whole span.
- Parâmetros
schedule (Intervals) – schedule of the employee, naive local datetimes
- Retorna
list of
(start, stop)naive datetimes in the employee’s timezone- Tipo de retorno
- _get_source_extra_fields_domain()[código fonte]¶
Only validated requests are time rule sources.
- Tipo de retorno
- _get_write_source_extra_source_fields()[código fonte]¶
Run the time rules again when the type or the state of a request changes.
- _get_time_rule_end_write_vals(end_utc, stop_local)[código fonte]¶
Return the values shortening a request to
end_utc.Writes
date_toand the request fields; requests by day or half day are flaggedis_time_rule_trimmedso that their end is not recomputed from the schedule.- Parâmetros
end_utc (datetime) – new end, naive UTC
stop_local (datetime) – the same instant in the employee’s timezone
- Tipo de retorno
- _get_time_rule_deficit_occupied(employee_id, start_utc, period_end_utc)[código fonte]¶
Return the validated time off of the employee within a period.
Deficit outputs are only placed outside these intervals.
- Parâmetros
employee_id (int) – employee id
start_utc (datetime) – naive UTC
period_end_utc (datetime) – naive UTC
- Retorna
intervals of naive UTC datetimes
- Tipo de retorno
Intervals
- _get_time_rule_output_vals(rule, df, dt, pp)[código fonte]¶
Return the creation values of an output time off.
- Tipo de retorno
- _get_time_rule_remainder_vals(df, dt)[código fonte]¶
Return the creation values of a remainder: a validated time off linked to the source.
- Parâmetros
df (datetime) – start, naive UTC
dt (datetime) – end, naive UTC
- Tipo de retorno
Additional fields with hr_holidays¶
- model odoo.addons.hr_holidays.models.hr_work_entry_type.HrWorkEntryType[código fonte]¶
-
- request_unit: str¶
- Required
- Name
Duration Type
- Selection
day: Full Dayhalf_day: Half-Dayhour: Custom Hours- Default
day
Define the minimum time off duration in which an employee can take when requesting a leave
- unit_of_measure: str¶
- Required
- Name
Unit
- Selection
hour: Hoursday: Days- Default
hour
Define if the time type will be allocated/accrued in hours or days
- leave_validation_type: str¶
- Name
Time Off Validation
- Selection
no_validation: Nonehr: By HR Responsiblemanager: By Time Off Approverboth: By HR Responsible and Time Off Approver- Default
hr
- allocation_validation_type: str¶
- Name
Approval
- Selection
no_validation: Nonehr: By HR Responsiblemanager: By Time Off Approverboth: By HR Responsible and Time Off Approver- Default
hr
- Select the level of approval needed in case of request by employee
# - No validation needed: The employee’s request is automatically approved. # - Approved by Time Off Officer: The employee’s request need to be manually approved # by the Time Off Officer, Employee’s Approver or both.
- employee_requests: bool¶
- Required
- Name
Allow Employee Requests
- Default
False
Extra Days Requests Allowed: User can request an allocation for himself.
Not Allowed: User cannot request an allocation.
- count_days_as: str¶
- Name
Count Days as
- Selection
working: Working Dayscalendar: Calendar Days- Default
working
If you take a leave on the whole week, worked days will result in a various number based on the working hours of the employee, calendar days will result in 7 in every case.
- include_public_holidays_in_duration: bool¶
- Name
Ignore Public Holidays
- Default
False
Public holidays should be counted in the leave duration when applying for leaves
- allows_negative: bool¶
- Name
Allow Negative
If checked, users request can exceed the allocated days and balance can go in negative.
- max_allowed_negative: int¶
- Name
Maximum Excess Amount
Define the maximum level of negative days this kind of time off can reach. Value must be at least 1.
- allow_request_on_top: bool¶
- Name
Allow Request on Top
- Default
False
If checked, users can request another leave on top of the ones of this type.
- elligible_for_accrual_rate: bool¶
- Name
Eligible for Accrual Rate
If checked, this time type will be taken into account for accruals computation.
- create_calendar_meeting: bool¶
- Name
Display Time Off in Calendar
- Default
True
If this field is checked, every leave request of this type will have a corresponding entry in the calendar application. There will be no entry if this stays unchecked.
- max_leaves: float¶
- Name
Maximum Allowed
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
This value is given by the sum of all time off requests with a positive value.
- leaves_taken: float¶
- Name
Time off Already Taken
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
This value is given by the sum of all time off requests with a negative value.
- virtual_remaining_leaves: float¶
- Name
Virtual Remaining Time Off
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
Maximum Time Off Allowed - Time Off Already Taken - Time Off Waiting Approval
- has_valid_allocation: bool¶
- Name
Has Valid Allocation
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
This indicates if it is still possible to use this type of leave
- get_allocation_data(employees, target_date=None, same_year_only=False)[código fonte]¶
Return the balance of the employees for each type of
selfon a date.Sums the data of
_get_consumed_leaves()over the allocations valid ontarget_date. Amounts are in theunit_of_measureof the type, rounded to 2 digits. Requests listed in the context keyignored_leave_idsare ignored.- Parâmetros
employees –
hr.employeerecordstarget_date –
date,datetimeor ISO string, today by defaultsame_year_only (bool) – only count the allocations starting in the year of
target_dateand the requests starting that year
- Retorna
{employee: [(type name, data, requires_allocation, type id), ...]}, wheredataholdsmax_leaves,leaves_takenandremaining_leaves(approved),virtual_leaves_takenandvirtual_remaining_leaves(also to approve),leaves_requested,leaves_approved,accrual_bonus,closest_allocation_expire(formatted date),closest_allocation_remaining,closest_allocation_duration,holds_changes,total_virtual_excess,virtual_excess_data,exceeding_durationand type information (request_unit,unit_of_measure,allows_negative,max_allowed_negative,color, …)- Tipo de retorno
- get_allocation_data_request(target_date=None, hidden_allocations=True, same_year_only=False)[código fonte]¶
Return the balances of the contextual employee for every type.
With the context key
from_dashboard, types without allocated time are left out.- Parâmetros
target_date – date of the balances, today by default
hidden_allocations (bool) – include the types hidden on the dashboard
same_year_only (bool) – see
get_allocation_data()
- Retorna
list of tuples, see
get_allocation_data()- Tipo de retorno
- get_work_entry_types_with_valid_allocations(date_from, date_to, employee_id)[código fonte]¶
Return the types of
selfthe employee can request time off of during a period.Types without allocation always; types requiring an allocation when a validated one covers the whole period and is an accrual or has a positive balance (within the negative cap).
- Parâmetros
date_from – first day
date_to – last day
employee_id (int) – employee id
- Tipo de retorno
hr.work.entry.type
- has_accrual_allocation()[código fonte]¶
Tell whether the contextual employee has a validated accrual allocation still running.
- Tipo de retorno
- has_future_allocation()[código fonte]¶
Tell whether the contextual employee has a validated allocation starting in the future.
- Tipo de retorno
- _get_closest_expiring_leaves_date_and_count(allocations, remaining_leaves, target_date, primary_unit)[código fonte]¶
Return the next date some remaining time expires, and how much.
Time expires at the end of an allocation, on a carry-over date when unused time is lost or limited, and at the end of the validity of carried over time.
- Parâmetros
allocations –
hr.leave.allocationwith remaining timeremaining_leaves (dict) –
{allocation: data}of_get_consumed_leaves()target_date (datetime.date) – reference date
primary_unit (str) –
'days'or'hours'
- Retorna
(date, amount),(None, 0)when nothing expires- Tipo de retorno
- _get_carried_over_days_expiration_data(allocations, target_date)[código fonte]¶
Return when the time carried over by accrual allocations expires, and how much.
- Retorna
{allocation: {'expiration_date': date or None, 'no_expiring_days': float}}- Tipo de retorno
- _search_valid(operator, value)[código fonte]¶
Search
has_valid_allocation: types with a validated allocation for an employee.The employee is the context’s
default_employee_id,employee_idor the user’s employee; the period isdefault_date_from/default_date_to(withtz) from the context, or the current year.
- _search(domain, offset=0, limit=None, order=None, **kwargs)[código fonte]¶
Sort the types with
_model_sorting_key()when an employee is in the context.Only when the default order is requested; the sort is done in Python before offset and limit are applied.
- _model_sorting_key(work_entry_type)[código fonte]¶
Return the sort key of the types in
_search()(sequence).
- _check_allow_request_on_top()[código fonte]¶
Forbid requests on top of absences.
- _check_elligible_for_accrual_rate()[código fonte]¶
Working time types always count for the accruals.
- _check_overlapping_public_holidays()[código fonte]¶
Forbid changing whether public holidays count when this year’s requests overlap one.
- _check_leaves_for_count_days_as()[código fonte]¶
Forbid changing
count_days_asonce requests of the type exist.
- check_allocation_requirement_edit_validity()[código fonte]¶
Forbid changing
requires_allocationonce requests of the type exist.
Original definition from hr_holidays¶
- model odoo.addons.hr_holidays.models.hr_leave_mandatory_day.HrLeaveMandatoryDay[código fonte]¶
- _name = hr.leave.mandatory.day¶
- start_date: datetime.date¶
- Required
- Name
Start Date
- end_date: datetime.date¶
- Required
- Name
End Date
- department_ids: Sequence[odoo.orm.commands.Command]¶
- Name
Departments
- Comodel
- job_ids: Sequence[odoo.orm.commands.Command]¶
- Name
Job Position
- Comodel
Additional fields with hr_holidays¶
- model odoo.addons.hr_holidays.models.hr_employee.HrEmployee[código fonte]¶
- leave_manager_id: int¶
- Name
Time Off Approver
- Comodel
res.users
Select the user responsible for approving “Time Off” of this employee. If empty, the approval is done by an Administrator or Approver (determined in settings/users).
- current_leave_state: str¶
- Name
Current Time Off Status
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
- Selection
confirm: Waiting Approvalrefuse: Refusedvalidate1: Waiting Second Approvalvalidate: Approvedcancel: Cancelled
- leave_date_from: datetime.date¶
- Name
From Date
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
- leave_date_to: datetime.date¶
- Name
To Date
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
- is_absent: bool¶
- Name
Absent Today
- Readonly
this field is not supposed to/cannot be set manually
- Store
this field is there only for technical reasons
- create(vals_list)[código fonte]¶
Default the time off approver to the manager’s user and give it the approver group.
- write(vals)[código fonte]¶
Keep the time off approver and the pending requests in sync with the employee.
The time off approver follows the manager when it was the previous manager’s user, the approver group is granted to new approvers and removed from former ones, and a new department is copied on the requests to approve or in the future.
- _get_consumed_leaves(work_entry_types, target_date=False, ignore_future=False, precomputed_allocations={}, same_year_only=False)[código fonte]¶
Compute, per allocation, the time off taken and the balance of the employees.
The requests to approve or approved (
'confirm','validate1','validate') of the given types are deducted from the validated allocations covering them, in this order: allocations with an end date (the earliest first), accrual allocations, then the others. Requests starting aftertarget_datewhile an accrual allocation runs are not deducted but rechecked against the future accrual. The amounts are in theunit_of_measureof each type. Requests listed in the context keyignored_leave_idsare ignored.- Parâmetros
work_entry_types –
hr.work.entry.typerecords to considertarget_date (datetime.date) – date of the balance, today by default; the accrual allocations include what they will have accrued by then
ignore_future (bool) – only consider requests starting by
target_dateand no future accrualprecomputed_allocations (dict) –
{allocation: allocation_data}already computed fortarget_date(seehr.leave.allocation._process_accrual_plans()), used as issame_year_only (bool) – only consider requests starting in the year of
target_date
- Retorna
(consumed, to_recheck):consumed[employee][work_entry_type][allocation]is a dict with the keys<unit>_max_leaves,<unit>_accrual_bonus(accrual granted bytarget_date),<unit>_leaves_takenand<unit>_remaining_leaves(approved requests only),<unit>_virtual_leaves_takenand<unit>_virtual_remaining_leaves(all requests), where<unit>isdaysorhoursafter the type’s unit, plus<other unit>_takenand<other unit>_remainingin the other unit. Types without allocation use the keyFalseinstead of an allocation.to_recheck[employee][work_entry_type]is a dict withexcess_days({date: {'amount', 'is_virtual', 'leave_id'}}, the time not covered by any allocation),to_recheck_leaves(the future requests not deducted) andexceeding_duration(negative or zero, what the future accrual will miss to cover them).
- Tipo de retorno
- _get_hours_per_day(date_from)[código fonte]¶
Return the hours per day of the employee’s calendar on
date_from.24 for a fully flexible calendar, 0 on an empty recordset. Single employee.
- Tipo de retorno
- _get_hours_for_date(target_date, day_period=None, count_non_working_days=False)[código fonte]¶
Return the local hours a working day of the employee starts and ends at.
From the schedule of the version on
target_date(the company’s schedule on an empty recordset). A day off borrows the hours of the nearest working day, the day after first; a fully flexible schedule returns(0, 24). Duration-based attendances, flexible schedules andcount_non_working_daysgive the hours per day centered on noon.- Parâmetros
target_date (datetime.date) – the day
day_period (str) –
'morning'or'afternoon'to get the hours of a half daycount_non_working_days (bool) – treat days off as working days
- Retorna
(hour_from, hour_to)as float hours- Tipo de retorno
- _get_mandatory_days(start_date, end_date)[código fonte]¶
Return the mandatory days applying to the employee within a period.
A mandatory day applies when it is in the employee’s company and has no calendar or the employee’s calendar, no job or the employee’s job, and no department or the employee’s department or one of its parents.
- Parâmetros
start_date (datetime.date) – first day
end_date (datetime.date) – last day
- Tipo de retorno
hr.leave.mandatory.day
- get_mandatory_days(start_date, end_date)[código fonte]¶
Return the colors of the mandatory days of the employee (or of the user’s employee).
- Retorna
{'YYYY-MM-DD': color}- Tipo de retorno
- get_mandatory_days_data(date_start, date_end)[código fonte]¶
Return the mandatory days of the contextual employee as calendar events.
- Retorna
list of dicts (
id,title,start,end,colorIndex, …)- Tipo de retorno
- _get_public_holidays(date_start, date_end)[código fonte]¶
Return the public holidays of the employee’s company and calendar within a period.
- Parâmetros
date_start – start of the period
date_end – end of the period
- Tipo de retorno
resource.calendar.leaves
- get_public_holidays_data(date_start, date_end)[código fonte]¶
Return the public holidays of the contextual employee as calendar events.
- Retorna
list of dicts (
id,title,start,end,isAllDay, …)- Tipo de retorno
- get_special_days_data(date_start, date_end)[código fonte]¶
Return the mandatory days and public holidays of the contextual employee.
Used by the calendar views.
- Retorna
{'mandatoryDays': [...], 'bankHolidays': [...]}, seeget_mandatory_days_data()andget_public_holidays_data()- Tipo de retorno
- get_time_off_dashboard_data(target_date=None)[código fonte]¶
Return the data of the time off dashboard of the contextual employee.
- Parâmetros
target_date – date of the balances, today by default
- Retorna
{'has_future_allocation', 'has_accrual_allocation', 'allocation_data', 'allocations_number'},allocation_databeing the result ofhr.work.entry.type.get_allocation_data_request()- Tipo de retorno
- get_allocations_number()[código fonte]¶
Return the number of allocations of the contextual employee waiting for approval.
- Tipo de retorno
- _get_contextual_employee()[código fonte]¶
Return the employee of the context, or the user’s employee.
The context keys
employee_idanddefault_employee_idare read in this order.- Tipo de retorno
hr.employee
- _compute_leave_status()[código fonte]¶
Compute the time off status of the employees now.
leave_date_from,current_leave_stateandis_absentcome from the validated time off in progress;leave_date_tois the day the employee is back: the first working day after the end of that time off or of the public holiday in progress.
- _get_first_working_interval_batch(min_dts)[código fonte]¶
Return the start of the first work interval of each employee after a datetime.
Looks up to two years ahead, in the calendars of the versions in contract, then in the current calendar.
- _adjust_leaves(leave_intervals)[código fonte]¶
Extend the leave intervals of time off by day or half day to whole days or halves.
A time off by day covers its days from midnight to midnight, a half day from midnight or noon to noon or midnight.
- Parâmetros
leave_intervals (Intervals) – leave intervals of one employee
- Tipo de retorno
Intervals
Additional fields with hr_holidays¶
- model odoo.addons.hr_holidays.models.hr_version.HrVersion[código fonte]¶
Write and Create: Special case when setting a contract as running: If there is already a validated time off over another contract with a different schedule, split the time off, before the _check_contracts raises an issue. If there are existing leaves that are spanned by this new contract, update their resource calendar to the current one.
- create(vals_list)[código fonte]¶
Create versions, moving the time off of the employees to the new working schedules.
See the class docstring; also creates the allocation of the working schedule’s accrual plan (
_action_trigger_accrual_plan_working_schedule()).
- write(vals)[código fonte]¶
Write on versions, moving the time off when the contract dates or the schedule change.
Time off spanning versions with different schedules is split, others get the new schedule. Changing the schedule also preserves the hours of allocations in hours and recreates the working schedule’s accrual allocation.
- _check_contracts()[código fonte]¶
Check that the time off of the versions does not span different working schedules.
- _get_leaves(extra_domain=None, min_date=None)[código fonte]¶
Return the time off of the versions’ employees ending after
min_date.- Parâmetros
extra_domain – domain added to the search
min_date (datetime.date) – defaults to the earliest start of the versions
- Tipo de retorno
hr.leave
- _get_leaves_from_vals(vals)[código fonte]¶
Return the time off a version created with
valsimpacts.The employee’s requests not refused or cancelled, on another schedule, within the contract.
- Parâmetros
vals (dict) – creation values of a version
- Tipo de retorno
hr.leave
- _check_overlapping_contract(leave)[código fonte]¶
Return the versions in contract overlapping
leave, sorted by start date.- Tipo de retorno
hr.version
- _update_leave_calendar(leave, overlapping_contracts)[código fonte]¶
Give
leavethe schedule of the first overlapping version and recompute its dates.- Parâmetros
leave –
hr.leaveoverlapping_contracts – see
_check_overlapping_contract()
- _update_leave_state(leave, leaves_state, refuse_leave=False)[código fonte]¶
Remember the state of
leave, then refuse it or reset it to'confirm'.
- _populate_all_new_leave_vals_from_split_leave(all_new_leave_origin, all_new_leave_vals, overlapping_contracts, leave, leaves_state)[código fonte]¶
Prepare one request per overlapping version to replace
leave.The parts keep the original state, except the last one which is to approve again.
- Retorna
(all_new_leave_origin, all_new_leave_vals), extended- Tipo de retorno
- _create_all_new_leave(all_new_leave_origin, all_new_leave_vals)[código fonte]¶
Create the requests prepared by
_populate_all_new_leave_vals_from_split_leave().Validated ones get their resource leaves; each one gets a link to its origin.
- _get_leave_work_entry_type(leave)[código fonte]¶
Return the type of the time off of the leave (
holiday_id), else the leave’s type.- Parâmetros
leave –
resource.calendar.leaves- Tipo de retorno
hr.work.entry.type
- _get_more_vals_leave_interval(interval, leaves)[código fonte]¶
Add
('leave_ids', time off)for the leaves of time off containinginterval.- Tipo de retorno
- _get_interval_leave_work_entry_type(interval, leaves, bypassing_codes)[código fonte]¶
Return the type of a leave interval, arbitrating overlapping leaves.
Priority: time off whose type code is in
bypassing_codes, then global leaves (public holidays), then other time off.
- _get_sub_leave_domain()[código fonte]¶
Also accept the leaves of the time off of the employees, whatever their calendar.
- Tipo de retorno
odoo.fields.Domain
- _generate_work_entries_postprocess_adapt_to_calendar(vals)[código fonte]¶
Compute the duration of time off not requested in hours from the schedule.
Time rule outputs keep their real span.
- _get_work_entry_source_fields()[código fonte]¶
Add
leave_idsto the keys merged when work entry values are combined.
- _action_trigger_accrual_plan_working_schedule()[código fonte]¶
Recreate the allocation granted by the accrual plan of the working schedule.
Working schedules with a work time rate above 100% and a
leave_accrual_plan_idgive the employee an accrual allocation over the version’s period (allocation_from_working_schedule_id), replacing the previous one.- Levanta
ValidationError – when the previous allocation was already used
Additional fields with hr_holidays¶
- model odoo.addons.hr_holidays.models.resource_calendar_leaves.ResourceCalendarLeaves[código fonte]¶
-
- elligible_for_accrual_rate: bool¶
- Name
Eligible for Accrual Rate
- Default
False
If checked, this time type will be taken into account for accruals computation.
- _check_compare_dates()[código fonte]¶
Forbid overlapping public holidays in the same company and calendar.
- _reevaluate_leaves(time_domain_dict)[código fonte]¶
Recompute the time off overlapping public holidays that were created, changed or deleted.
The durations are recomputed and the employees notified of the difference; a request whose allocation no longer covers it is refused.
- Parâmetros
time_domain_dict (list) – see
_get_time_domain_dict()
- _get_domain(time_domain_dict)[código fonte]¶
Return the domain of the time off impacted by public holidays.
Requests of the company overlapping one of the periods, not refused or cancelled, and not generated by time rules.
- Parâmetros
time_domain_dict (list) – see
_get_time_domain_dict()- Tipo de retorno
odoo.fields.Domain
- _get_time_domain_dict()[código fonte]¶
Return the company and the period of each global leave of
self.- Retorna
list of
{'company_id', 'date_from', 'date_to'}- Tipo de retorno
- _prepare_public_holidays_data(start_date, end_date)[código fonte]¶
Prepare the public holidays of the user’s companies from the shipped CSV files.
Reads
hr_holidays/data/public_holidays/public_holidays_<country>.csvand skips the holidays overlapping existing global leaves.- Parâmetros
start_date (datetime.date) – first day
end_date (datetime.date) – last day
- Retorna
dict with
prepared_public_holidays({company_id: [values]}) and the companiescompanies_without_country,companies_without_public_holidaysandcompanies_with_all_existing_holidays- Tipo de retorno
- _cron_generate_public_holidays()[código fonte]¶
Cron: create the public holidays of the next year from the shipped CSV files.
- _ensure_datetime(datetime_representation, date_format=None)[código fonte]¶
Return
datetime_representationas a datetime, parsing strings withdate_format.- Retorna
the datetime,
Nonewhen it cannot be parsed- Tipo de retorno
Additional fields with hr_holidays¶
- model odoo.addons.hr_holidays.models.hr_employee_departure.HrEmployeeDeparture[código fonte]¶
- _cleanup_employee_departure_leaves()[código fonte]¶
Clean up the employee’s leaves and allocations when processing their departure, optionally refusing future leaves instead of deleting them.
- _check_refuse_future_leaves_condition()[código fonte]¶
Return whether future leaves should be refused. Can be overridden by localizations.
Additional fields with hr_holidays¶
- model odoo.addons.hr_holidays.models.resource_resource.ResourceResource[código fonte]¶
- leave_date_to: datetime.date¶
- Name
None
- _format_leave(leave, resource_hours_per_day, resource_hours_per_week, ranges_to_remove, start_day, end_day, locale)[código fonte]¶
Remove the time off by half day or in hours from the planning of the resource.
They only cover a half day or their hours of a single day; other leaves are handled by
resource.
Original definition from hr_holidays¶
- model odoo.addons.hr_holidays.models.hr_leave_display_name_mixin.HrLeaveDisplayNameMixin[código fonte]¶
- _name = hr.leave.display.name.mixin¶
- _get_leave_duration_display(request_unit, number_of_hours, number_of_days)[código fonte]¶
Format duration string based on request unit (hours or days)
- _get_leave_display_date(date_from_utc, date_to_utc, number_of_days)[código fonte]¶
Format display date range string