[REF] hr_holidays: improve leave form view and simplify duration encoding
Purpose of this commit is to simplify leave request encoding. We want less options and more straightforward encoding of leave requests. Specifications * taking half-day leaves is limited to one half day. It is not possible anymore to take leaves in half days that span on several days. WHen choosing half day the user choose whether he takes the morning or the afternoon of the given day; * choosing half-days leaves spanning on several days can be done taking several leaves if necessary. It is considered as a corner case that should not bloat the interface; * taking hours-based leaves is limited to a given day. It is not possible anymore to take leaves given some start and end hours that span on several days. When choosing hours the user choose the start and end hours using a selection for every half-hour for the given day; * choosing hours-based leaves spanning on several days can be done taking several leaves if necessary. It is considered as a corner case that should not bloat the interface; * taking leaves spanning on several days is necessarily done with full length days; Various misc specifications about form view cleaning * hide "To submit" stage in the stage bar; * move description below duration information; * remove display name; Duration computation, various fields and form view are updated accordingly to this specification. This commit is linked to task ID 1876795 and PR #26571.
This commit is contained in:
@@ -6,11 +6,11 @@
|
||||
import logging
|
||||
import math
|
||||
|
||||
from datetime import timedelta, datetime, time
|
||||
from datetime import datetime
|
||||
from pytz import timezone, UTC
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo.addons.resource.models.resource import float_to_time
|
||||
from odoo.addons.resource.models.resource import float_to_time, HOURS_PER_DAY
|
||||
from odoo.exceptions import AccessError, UserError, ValidationError
|
||||
from odoo.tools import float_compare
|
||||
from odoo.tools.translate import _
|
||||
@@ -62,6 +62,7 @@ class HolidaysRequest(models.Model):
|
||||
@api.model
|
||||
def default_get(self, fields_list):
|
||||
defaults = super(HolidaysRequest, self).default_get(fields_list)
|
||||
defaults = self._default_get_request_parameters(defaults)
|
||||
|
||||
LeaveType = self.env['hr.leave.type'].with_context(employee_id=defaults.get('employee_id'), default_date_from=defaults.get('date_from', fields.Datetime.now()))
|
||||
lt = LeaveType.search([('valid', '=', True)])
|
||||
@@ -72,6 +73,26 @@ class HolidaysRequest(models.Model):
|
||||
def _default_employee(self):
|
||||
return self.env.context.get('default_employee_id') or self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
|
||||
|
||||
def _default_get_request_parameters(self, values):
|
||||
new_values = dict(values)
|
||||
global_from, global_to = False, False
|
||||
# TDE FIXME: consider a mapping on several days that is not the standard
|
||||
# calendar widget 7-19 in user's TZ is some custom input
|
||||
if values.get('date_from'):
|
||||
user_tz = self.env.user.tz or 'UTC'
|
||||
localized_dt = timezone('UTC').localize(values['date_from']).astimezone(timezone(user_tz))
|
||||
global_from = localized_dt.time().hour == 7 and localized_dt.time().minute == 0
|
||||
new_values['request_date_from'] = values['date_from'].date()
|
||||
if values.get('date_to'):
|
||||
user_tz = self.env.user.tz or 'UTC'
|
||||
localized_dt = timezone('UTC').localize(values['date_to']).astimezone(timezone(user_tz))
|
||||
global_to = localized_dt.time().hour == 19 and localized_dt.time().minute == 0
|
||||
new_values['request_date_to'] = values['date_to'].date()
|
||||
if global_from and global_to:
|
||||
new_values['request_unit_custom'] = True
|
||||
return new_values
|
||||
|
||||
# description
|
||||
name = fields.Char('Description')
|
||||
state = fields.Selection([
|
||||
('draft', 'To Submit'),
|
||||
@@ -107,9 +128,11 @@ class HolidaysRequest(models.Model):
|
||||
# duration
|
||||
date_from = fields.Datetime(
|
||||
'Start Date', readonly=True, index=True, copy=False, required=True,
|
||||
default=fields.Datetime.now,
|
||||
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, track_visibility='onchange')
|
||||
date_to = fields.Datetime(
|
||||
'End Date', readonly=True, copy=False, required=True,
|
||||
default=fields.Datetime.now,
|
||||
states={'draft': [('readonly', False)], 'confirm': [('readonly', False)]}, track_visibility='onchange')
|
||||
number_of_days = fields.Float(
|
||||
'Duration (Days)', copy=False, readonly=True, track_visibility='onchange',
|
||||
@@ -143,20 +166,72 @@ class HolidaysRequest(models.Model):
|
||||
help='This area is automaticly filled by the user who validate the leave with second level (If Leave type need second validation)')
|
||||
can_reset = fields.Boolean('Can reset', compute='_compute_can_reset')
|
||||
can_approve = fields.Boolean('Can Approve', compute='_compute_can_approve')
|
||||
# UX FIELDS
|
||||
# used when not using hour-based computation
|
||||
|
||||
# UX fields
|
||||
leave_type_request_unit = fields.Selection(related='holiday_status_id.request_unit', readonly=True)
|
||||
# Interface fields used when not using hour-based computation
|
||||
request_date_from = fields.Date('Request Start Date')
|
||||
request_date_to = fields.Date('Request End Date')
|
||||
# Interface fields used when using hour-based computation
|
||||
request_hour_from = fields.Selection([
|
||||
(0, '12:00 PM'), (0.5, '0:30 AM'),
|
||||
(1, '1:00 AM'), (1.5, '1:30 AM'),
|
||||
(2, '2:00 AM'), (2.5, '2:30 AM'),
|
||||
(3, '3:00 AM'), (3.5, '3:30 AM'),
|
||||
(4, '4:00 AM'), (4.5, '4:30 AM'),
|
||||
(5, '5:00 AM'), (5.5, '5:30 AM'),
|
||||
(6, '6:00 AM'), (6.5, '6:30 AM'),
|
||||
(7, '7:00 AM'), (7.5, '7:30 AM'),
|
||||
(8, '8:00 AM'), (8.5, '8:30 AM'),
|
||||
(9, '9:00 AM'), (9.5, '9:30 AM'),
|
||||
(10, '10:00 AM'), (10.5, '10:30 AM'),
|
||||
(11, '11:00 AM'), (11.5, '11:30 AM'),
|
||||
(12, '12:00 AM'), (12.5, '0:30 PM'),
|
||||
(13, '1:00 PM'), (13.5, '1:30 PM'),
|
||||
(14, '2:00 PM'), (14.5, '2:30 PM'),
|
||||
(15, '3:00 PM'), (15.5, '3:30 PM'),
|
||||
(16, '4:00 PM'), (16.5, '4:30 PM'),
|
||||
(17, '5:00 PM'), (17.5, '5:30 PM'),
|
||||
(18, '6:00 PM'), (18.5, '6:30 PM'),
|
||||
(19, '7:00 PM'), (19.5, '7:30 PM'),
|
||||
(20, '8:00 PM'), (20.5, '8:30 PM'),
|
||||
(21, '9:00 PM'), (21.5, '9:30 PM'),
|
||||
(22, '10:00 PM'), (22.5, '10:30 PM'),
|
||||
(23, '11:00 PM'), (23.5, '11:30 PM')], string='Hour from')
|
||||
request_hour_to = fields.Selection([
|
||||
(0, '12:00 PM'), (0.5, '0:30 AM'),
|
||||
(1, '1:00 AM'), (1.5, '1:30 AM'),
|
||||
(2, '2:00 AM'), (2.5, '2:30 AM'),
|
||||
(3, '3:00 AM'), (3.5, '3:30 AM'),
|
||||
(4, '4:00 AM'), (4.5, '4:30 AM'),
|
||||
(5, '5:00 AM'), (5.5, '5:30 AM'),
|
||||
(6, '6:00 AM'), (6.5, '6:30 AM'),
|
||||
(7, '7:00 AM'), (7.5, '7:30 AM'),
|
||||
(8, '8:00 AM'), (8.5, '8:30 AM'),
|
||||
(9, '9:00 AM'), (9.5, '9:30 AM'),
|
||||
(10, '10:00 AM'), (10.5, '10:30 AM'),
|
||||
(11, '11:00 AM'), (11.5, '11:30 AM'),
|
||||
(12, '12:00 AM'), (12.5, '0:30 PM'),
|
||||
(13, '1:00 PM'), (13.5, '1:30 PM'),
|
||||
(14, '2:00 PM'), (14.5, '2:30 PM'),
|
||||
(15, '3:00 PM'), (15.5, '3:30 PM'),
|
||||
(16, '4:00 PM'), (16.5, '4:30 PM'),
|
||||
(17, '5:00 PM'), (17.5, '5:30 PM'),
|
||||
(18, '6:00 PM'), (18.5, '6:30 PM'),
|
||||
(19, '7:00 PM'), (19.5, '7:30 PM'),
|
||||
(20, '8:00 PM'), (20.5, '8:30 PM'),
|
||||
(21, '9:00 PM'), (21.5, '9:30 PM'),
|
||||
(22, '10:00 PM'), (22.5, '10:30 PM'),
|
||||
(23, '11:00 PM'), (23.5, '11:30 PM')], string='Hour to')
|
||||
# used only when the leave is taken in half days
|
||||
request_date_from_period = fields.Selection([
|
||||
('am', 'Morning'), ('pm', 'Afternoon')],
|
||||
string="Date Period Start", default='am')
|
||||
request_date_to_period = fields.Selection([
|
||||
('am', 'Morning'), ('pm', 'Afternoon')],
|
||||
string="Date Period End", default='pm')
|
||||
# request type
|
||||
request_unit = fields.Selection([('day', '1 Day'),
|
||||
('period', 'Period')], default='day')
|
||||
request_unit_half = fields.Boolean('Half Day')
|
||||
request_unit_hours = fields.Boolean('Custom Hours')
|
||||
request_unit_custom = fields.Boolean('Days-long custom hours')
|
||||
|
||||
_sql_constraints = [
|
||||
('type_value', "CHECK( (holiday_type='employee' AND employee_id IS NOT NULL) or (holiday_type='category' AND category_id IS NOT NULL) or (holiday_type='department' AND department_id IS NOT NULL) )",
|
||||
"The employee, department or employee category of this request is missing. Please make sure that your user login is linked to an employee."),
|
||||
@@ -164,69 +239,70 @@ class HolidaysRequest(models.Model):
|
||||
('duration_check', "CHECK ( number_of_days >= 0 )", "If you want to change the number of days you should use the 'period' mode"),
|
||||
]
|
||||
|
||||
@api.onchange('request_unit', 'request_date_from_period', 'request_date_to_period',
|
||||
'holiday_status_id', 'request_date_from', 'request_date_to', 'employee_id')
|
||||
@api.onchange('request_date_from_period', 'request_hour_from', 'request_hour_to',
|
||||
'request_date_from', 'request_date_to',
|
||||
'employee_id')
|
||||
def _onchange_request_parameters(self):
|
||||
date_from = False
|
||||
date_to = False
|
||||
|
||||
if not self.employee_id:
|
||||
if not self.request_date_from:
|
||||
self.date_from = False
|
||||
return
|
||||
|
||||
if self.request_date_from:
|
||||
if self.date_from:
|
||||
date_from = fields.Datetime.to_string(datetime.combine(fields.Date.from_string(self.request_date_from), fields.Datetime.from_string(self.date_from).time()))
|
||||
else:
|
||||
date_from = datetime.combine(self.request_date_from, time.min)
|
||||
if self.request_unit_half or self.request_unit_hours:
|
||||
self.request_date_to = self.request_date_from
|
||||
|
||||
if self.request_date_to:
|
||||
if self.date_to:
|
||||
date_to = fields.Datetime.to_string(datetime.combine(fields.Date.from_string(self.request_date_to), fields.Datetime.from_string(self.date_to).time()))
|
||||
else:
|
||||
date_to = datetime.combine(self.request_date_to, time.max)
|
||||
|
||||
if not self.request_date_from or not self.request_date_to:
|
||||
if date_from:
|
||||
self.date_from = date_from
|
||||
if date_to:
|
||||
self.date_to = date_to
|
||||
self.number_of_days = 0
|
||||
if not self.request_date_to:
|
||||
self.date_to = False
|
||||
return
|
||||
|
||||
domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id)]
|
||||
domain = [('calendar_id', '=', self.employee_id.resource_calendar_id.id or self.env.user.company_id.resource_calendar_id.id)]
|
||||
attendances = self.env['resource.calendar.attendance'].search(domain, order='dayofweek, day_period DESC')
|
||||
|
||||
first_day = fields.Date.from_string(date_from)
|
||||
last_day = fields.Date.from_string(date_to)
|
||||
|
||||
if self.request_unit in ['day']:
|
||||
last_day = first_day
|
||||
|
||||
# find first attendance coming after first_day
|
||||
attendance_from = next((att for att in attendances if int(att.dayofweek) >= first_day.weekday()), attendances[0])
|
||||
attendance_from = next((att for att in attendances if int(att.dayofweek) >= self.request_date_from.weekday()), attendances[0])
|
||||
# find last attendance coming before last_day
|
||||
attendance_to = next((att for att in reversed(attendances) if int(att.dayofweek) <= last_day.weekday()), attendances[-1])
|
||||
attendance_to = next((att for att in reversed(attendances) if int(att.dayofweek) <= self.request_date_to.weekday()), attendances[-1])
|
||||
|
||||
if self.request_unit == 'day' or (self.request_unit == 'period' and self.leave_type_request_unit == 'day'):
|
||||
if self.request_unit_half:
|
||||
if self.request_date_from_period == 'am':
|
||||
hour_from = float_to_time(attendance_from.hour_from)
|
||||
hour_to = float_to_time(attendance_from.hour_to)
|
||||
else:
|
||||
hour_from = float_to_time(attendance_to.hour_from)
|
||||
hour_to = float_to_time(attendance_to.hour_to)
|
||||
elif self.request_unit_hours:
|
||||
hour_from = float_to_time(self.request_hour_from)
|
||||
hour_to = float_to_time(self.request_hour_to)
|
||||
elif self.request_unit_custom:
|
||||
hour_from = self.date_from.time()
|
||||
hour_to = self.date_to.time()
|
||||
else:
|
||||
hour_from = float_to_time(attendance_from.hour_from)
|
||||
hour_to = float_to_time(attendance_to.hour_to)
|
||||
|
||||
if self.request_unit == 'period' and self.leave_type_request_unit == 'hour':
|
||||
date_from = fields.Datetime.from_string(date_from)
|
||||
date_to = fields.Datetime.from_string(date_to)
|
||||
else:
|
||||
tz = self.env.user.tz or 'UTC'
|
||||
date_from = timezone(tz).localize(datetime.combine(first_day, hour_from)).astimezone(UTC).replace(tzinfo=None)
|
||||
date_to = timezone(tz).localize(datetime.combine(last_day, hour_to)).astimezone(UTC).replace(tzinfo=None)
|
||||
tz = self.env.user.tz if self.env.user.tz and not self.request_unit_custom else 'UTC' # custom -> already in UTC
|
||||
self.date_from = timezone(tz).localize(datetime.combine(self.request_date_from, hour_from)).astimezone(UTC).replace(tzinfo=None)
|
||||
self.date_to = timezone(tz).localize(datetime.combine(self.request_date_to, hour_to)).astimezone(UTC).replace(tzinfo=None)
|
||||
|
||||
self.date_from = date_from
|
||||
self.date_to = date_to
|
||||
@api.onchange('request_unit_half')
|
||||
def _onchange_request_unit_half(self):
|
||||
if self.request_unit_half:
|
||||
self.request_unit_hours = False
|
||||
self.request_unit_custom = False
|
||||
self._onchange_request_parameters()
|
||||
|
||||
if not (self.request_unit == 'period' and self.leave_type_request_unit == 'hour'):
|
||||
date_from = date_from
|
||||
date_to = date_to
|
||||
@api.onchange('request_unit_hours')
|
||||
def _onchange_request_unit_hours(self):
|
||||
if self.request_unit_hours:
|
||||
self.request_unit_half = False
|
||||
self.request_unit_custom = False
|
||||
self._onchange_request_parameters()
|
||||
|
||||
self.number_of_days = self._get_number_of_days(date_from, date_to, self.employee_id.id)
|
||||
@api.onchange('request_unit_custom')
|
||||
def _onchange_request_unit_custom(self):
|
||||
if self.request_unit_custom:
|
||||
self.request_unit_half = False
|
||||
self.request_unit_hours = False
|
||||
self._onchange_request_parameters()
|
||||
|
||||
@api.onchange('holiday_type')
|
||||
def _onchange_type(self):
|
||||
@@ -241,54 +317,18 @@ class HolidaysRequest(models.Model):
|
||||
self.employee_id = None
|
||||
self.department_id = None
|
||||
|
||||
@api.onchange('date_from')
|
||||
def _onchange_date_from(self):
|
||||
""" If there are no date set for date_to, automatically set one 8 hours later than
|
||||
the date_from. Also update the number_of_days.
|
||||
"""
|
||||
date_from = fields.Datetime.from_string(self.date_from)
|
||||
date_to = fields.Datetime.from_string(self.date_to)
|
||||
|
||||
# No date_to set so far: automatically compute one 8 hours later
|
||||
if date_from and not date_to:
|
||||
date_to = date_from + timedelta(hours=self.employee_id.resource_calendar_id.hours_per_day)
|
||||
self.date_to = date_to
|
||||
|
||||
self.request_date_from = date_from.date() if date_from else False
|
||||
self.request_date_to = date_to.date() if date_to else False
|
||||
|
||||
if (date_from and date_to) and (date_from.day < date_to.day):
|
||||
self.request_unit = 'period'
|
||||
|
||||
# Compute and update the number of days
|
||||
if (date_to and date_from) and (date_from <= date_to):
|
||||
self.number_of_days = self._get_number_of_days(date_from, date_to, self.employee_id.id)
|
||||
else:
|
||||
self.number_of_days = 0
|
||||
|
||||
@api.onchange('date_to')
|
||||
def _onchange_date_to(self):
|
||||
""" Update the number_of_days. """
|
||||
date_from = fields.Datetime.from_string(self.date_from)
|
||||
date_to = fields.Datetime.from_string(self.date_to)
|
||||
|
||||
self.request_date_from = date_from.date() if date_from else False
|
||||
self.request_date_to = date_to.date() if date_to else False
|
||||
|
||||
if (date_from and date_to) and (date_from.day < date_to.day):
|
||||
self.request_unit = 'period'
|
||||
|
||||
# Compute and update the number of days
|
||||
if (date_to and date_from) and (date_from <= date_to):
|
||||
self.number_of_days = self._get_number_of_days(date_from, date_to, self.employee_id.id)
|
||||
else:
|
||||
self.number_of_days = 0
|
||||
|
||||
@api.onchange('employee_id')
|
||||
def _onchange_employee_id(self):
|
||||
self.manager_id = self.employee_id and self.employee_id.parent_id
|
||||
self.department_id = self.employee_id.department_id
|
||||
|
||||
@api.onchange('date_from', 'date_to')
|
||||
def _onchange_leave_dates(self):
|
||||
if self.date_from and self.date_to:
|
||||
self.number_of_days = self._get_number_of_days(self.date_from, self.date_to, self.employee_id.id)
|
||||
else:
|
||||
self.number_of_days = 0
|
||||
|
||||
@api.multi
|
||||
@api.depends('number_of_days')
|
||||
def _compute_number_of_days_display(self):
|
||||
@@ -299,7 +339,8 @@ class HolidaysRequest(models.Model):
|
||||
@api.depends('number_of_days')
|
||||
def _compute_number_of_hours_display(self):
|
||||
for holiday in self:
|
||||
holiday.number_of_hours_display = holiday.number_of_days * self.employee_id.resource_calendar_id.hours_per_day
|
||||
calendar = self.employee_id.resource_calendar_id or self.env.user.company_id.resource_calendar_id
|
||||
holiday.number_of_hours_display = holiday.number_of_days * (calendar.hours_per_day or HOURS_PER_DAY)
|
||||
|
||||
@api.multi
|
||||
@api.depends('state', 'employee_id', 'department_id')
|
||||
@@ -485,11 +526,12 @@ class HolidaysRequest(models.Model):
|
||||
@api.multi
|
||||
def _prepare_holidays_meeting_values(self):
|
||||
self.ensure_one()
|
||||
calendar = self.employee_id.resource_calendar_id or self.env.user.company_id.resource_calendar_id
|
||||
meeting_values = {
|
||||
'name': self.display_name,
|
||||
'categ_ids': [(6, 0, [
|
||||
self.holiday_status_id.categ_id.id])] if self.holiday_status_id.categ_id else [],
|
||||
'duration': self.number_of_days * self.employee_id.resource_calendar_id.hours_per_day,
|
||||
'duration': self.number_of_days * (calendar.hours_per_day or HOURS_PER_DAY),
|
||||
'description': self.notes,
|
||||
'user_id': self.user_id.id,
|
||||
'start': self.date_from,
|
||||
|
||||
@@ -27,8 +27,11 @@ class HolidaysAllocation(models.Model):
|
||||
return self.env.context.get('default_employee_id') or self.env['hr.employee'].search([('user_id', '=', self.env.uid)], limit=1)
|
||||
|
||||
def _default_holiday_status_id(self):
|
||||
lt = self.env['hr.leave.type'].with_context(employee_id=self._default_employee().id).search([('valid', '=', True)], limit=1)
|
||||
return lt[:1]
|
||||
if self.user_has_groups('hr_holidays.group_hr_holidays_user'):
|
||||
domain = [('valid', '=', True)]
|
||||
else:
|
||||
domain = [('valid', '=', True), ('allocation_type', 'in', ('no', 'fixed_allocation'))]
|
||||
return self.env['hr.leave.type'].search(domain, limit=1)
|
||||
|
||||
name = fields.Char('Description')
|
||||
state = fields.Selection([
|
||||
|
||||
@@ -150,13 +150,19 @@ class HolidaysType(models.Model):
|
||||
|
||||
return result
|
||||
|
||||
def _get_contextual_employee_id(self):
|
||||
if 'employee_id' in self._context:
|
||||
employee_id = self._context['employee_id']
|
||||
elif 'default_employee_id' in self._context:
|
||||
employee_id = self._context['default_employee_id']
|
||||
else:
|
||||
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.user.id)], limit=1).id
|
||||
return employee_id
|
||||
|
||||
@api.multi
|
||||
def _compute_leaves(self):
|
||||
data_days = {}
|
||||
if 'employee_id' in self._context:
|
||||
employee_id = self._context['employee_id']
|
||||
else:
|
||||
employee_id = self.env['hr.employee'].search([('user_id', '=', self.env.user.id)], limit=1).id
|
||||
employee_id = self._get_contextual_employee_id()
|
||||
|
||||
if employee_id:
|
||||
data_days = self.get_days(employee_id)
|
||||
@@ -221,8 +227,9 @@ class HolidaysType(models.Model):
|
||||
is an employee_id in context and that no other order has been given
|
||||
to the method.
|
||||
"""
|
||||
employee_id = self._get_contextual_employee_id()
|
||||
leave_ids = super(HolidaysType, self)._search(args, offset=offset, limit=limit, order=order, count=count, access_rights_uid=access_rights_uid)
|
||||
if not count and not order and self._context.get('employee_id'):
|
||||
if not count and not order and employee_id:
|
||||
leaves = self.browse(leave_ids)
|
||||
sort_key = lambda l: (l.allocation_type == 'fixed', l.allocation_type == 'fixed_allocation', l.virtual_remaining_leaves)
|
||||
return leaves.sorted(key=sort_key, reverse=True).ids
|
||||
|
||||
@@ -89,17 +89,13 @@
|
||||
<button string="Refuse" name="action_refuse" type="object" attrs="{'invisible': ['|', ('can_approve', '=', False), ('state', 'not in', ('confirm','validate','validate1'))]}"/>
|
||||
<button string="Reset to Draft" name="action_draft" type="object"
|
||||
attrs="{'invisible': ['|', ('can_reset', '=', False), ('state', 'not in', ['confirm', 'refuse'])]}"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm,validate"/>
|
||||
<field name="state" widget="statusbar" statusbar_visible="confirm,validate"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<div class="oe_title">
|
||||
<h1><field name="display_name"/></h1>
|
||||
</div>
|
||||
<field name="leave_type_request_unit" invisible="1"/>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" attrs="{'readonly':[('state','!=','draft'),('state','!=','confirm')]}"/>
|
||||
<field name="holiday_status_id" context="{'employee_id':employee_id, 'default_date_from':date_from}"/>
|
||||
<field name="holiday_status_id" context="{'employee_id':employee_id, 'default_date_from':date_from}" options="{'no_create': True, 'no_open': True}"/>
|
||||
|
||||
<field name="number_of_days" invisible="1"/>
|
||||
<label for="number_of_days_display" string="Duration"/>
|
||||
@@ -112,25 +108,70 @@
|
||||
<field name="number_of_hours_display" nolabel="1" class="oe_inline"/>
|
||||
<span class="ml8">Hours</span>
|
||||
</div>
|
||||
<field name="request_unit" widget="radio" attrs="{'readonly': [('state', '=', 'validate')]}"/>
|
||||
</div>
|
||||
|
||||
<div class="o_row">
|
||||
<span attrs="{'invisible': [('request_unit', '!=', 'period')]}">From </span>
|
||||
<field name="request_date_from" attrs="{'readonly': [('state', '=', 'validate')], 'invisible': [('leave_type_request_unit', '=', 'hour'), ('request_unit', '=', 'period')]}"/>
|
||||
<field name="date_from" attrs="{'readonly': [('state', '=', 'validate')], 'invisible': ['|', ('leave_type_request_unit', '!=', 'hour'), ('request_unit', '!=', 'period')]}"/>
|
||||
<span class="ml8" attrs="{'invisible': ['|', '&', ('request_unit', '!=', 'half'), ('leave_type_request_unit', '!=', 'half'), '&', ('request_unit', '=', 'day'), ('leave_type_request_unit', '=', 'half')]}"/>
|
||||
<field name="request_date_from_period" options="{'horizontal': True}"
|
||||
attrs="{'readonly': [('state', '=', 'validate')], 'invisible': ['|', '|', ('leave_type_request_unit', '=', 'day'), '&', ('leave_type_request_unit', '=', 'half'), ('request_unit', '=', 'day'), '&', ('leave_type_request_unit', '=', 'hour'), ('request_unit', '!=', 'half')]}"/>
|
||||
<label for="request_date_from" string="From"/>
|
||||
<div>
|
||||
<field name="date_from" invisible="1"/>
|
||||
<field name="date_to" invisible="1"/>
|
||||
<div class="o_row o_row_readonly">
|
||||
<field name="request_date_from" class="oe_inline"
|
||||
attrs="{'readonly': [('state', 'not in', ('draft', 'confirm'))]}"/>
|
||||
<span class="oe_inline"
|
||||
attrs="{'invisible': ['|', ('request_unit_half', '=', True), ('request_unit_hours', '=', True)]}">
|
||||
To
|
||||
</span>
|
||||
<field name="request_date_to" class="oe_inline"
|
||||
attrs="{
|
||||
'readonly': [('state', 'not in', ('draft', 'confirm'))],
|
||||
'invisible': ['|', ('request_unit_half', '=', True), ('request_unit_hours', '=', True)]
|
||||
}"/>
|
||||
<field name="request_date_from_period" class="oe_inline"
|
||||
string="In"
|
||||
options="{'horizontal': True}"
|
||||
attrs="{
|
||||
'readonly': [('state', 'not in', ('draft', 'confirm'))],
|
||||
'required': [('request_unit_half', '=', True)],
|
||||
'invisible': [('request_unit_half', '=', False)]}"/>
|
||||
</div>
|
||||
<div class="o_row">
|
||||
<span attrs="{'invisible': [('request_unit', '!=', 'period')]}">To </span>
|
||||
<field name="request_date_to" attrs="{'readonly': [('state', '=', 'validate')], 'invisible': ['|', ('request_unit', '!=', 'period'), ('leave_type_request_unit', '=', 'hour')]}"/>
|
||||
<field name="date_to" attrs="{'readonly': [('state', '=', 'validate')], 'invisible': ['|', ('leave_type_request_unit', '!=', 'hour'), ('request_unit', '!=', 'period')], 'required': [('request_unit', '=', 'period')]}"/>
|
||||
<span class="ml8" attrs="{'invisible': ['|', ('leave_type_request_unit', '!=', 'half'), ('request_unit', '!=', 'period')]}"/>
|
||||
<field name="request_date_to_period" options="{'horizontal': True}"
|
||||
attrs="{'readonly': [('state', '=', 'validate')], 'invisible': ['|', ('leave_type_request_unit', '!=', 'half'), ('request_unit', '!=', 'period')]}"/>
|
||||
<div class="o_row o_row_readonly">
|
||||
<label for="request_unit_half"
|
||||
attrs="{'readonly': [('state', 'not in', ('draft', 'confirm'))]}"/>
|
||||
<field name="request_unit_half"
|
||||
attrs="{'readonly': [('state', 'not in', ('draft', 'confirm'))]}"/>
|
||||
<label for="request_unit_hours" attrs="{
|
||||
'readonly': [('state', 'not in', ('draft', 'confirm'))],
|
||||
'invisible': [('leave_type_request_unit', '!=', 'hour')]
|
||||
}"/>
|
||||
<field name="request_unit_hours" attrs="{
|
||||
'readonly': [('state', 'not in', ('draft', 'confirm'))],
|
||||
'invisible': [('leave_type_request_unit', '!=', 'hour')]
|
||||
}"/>
|
||||
<label for="request_unit_custom" invisible="1" attrs="{
|
||||
'readonly': [('state', 'not in', ('draft', 'confirm'))],
|
||||
}"/>
|
||||
<field name="request_unit_custom" invisible="1" attrs="{
|
||||
'readonly': [('state', 'not in', ('draft', 'confirm'))],
|
||||
}"/>
|
||||
</div>
|
||||
<div class="o_row o_row_readonly">
|
||||
<label for="request_hour_from" string="From"
|
||||
attrs="{'invisible': [('request_unit_hours', '=', False)]}"/>
|
||||
<field name="request_hour_from"
|
||||
attrs="{
|
||||
'readonly': [('state', '=', 'validate')],
|
||||
'required': [('request_unit_hours', '=', True)],
|
||||
'invisible': [('request_unit_hours', '=', False)]}"/>
|
||||
<label for="request_hour_to" string="To"
|
||||
attrs="{'invisible': [('request_unit_hours', '=', False)]}"/>
|
||||
<field name="request_hour_to"
|
||||
attrs="{
|
||||
'readonly': [('state', '=', 'validate')],
|
||||
'required': [('request_unit_hours', '=', True)],
|
||||
'invisible': [('request_unit_hours', '=', False)]}"/>
|
||||
</div>
|
||||
</div>
|
||||
<field name="name" attrs="{'readonly': [('state', 'not in', ('draft', 'confirm'))]}"/>
|
||||
</group>
|
||||
<group name="col_right">
|
||||
<field name="employee_id" invisible="1"/>
|
||||
|
||||
Reference in New Issue
Block a user