From 1b512efdac4bdfe2fd66eb910ad2c6f707998887 Mon Sep 17 00:00:00 2001 From: hapa-odoo Date: Wed, 15 Feb 2023 06:18:56 +0000 Subject: [PATCH] [IMP] holiday: improve UX holiday timeoff MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit -Display the state of a time off that you open from the dashboard -Rename Stress Days into "Mandatory Days" -My Allocations  Remove "Employee" from the Group By Replace filter `Current Year` with `Currently Valid`. -My Time Off -Remove Employees from list view and kanban view -Create an allocation / allocation request form - Create an allocation ux : employee side- compute the name of the allocation. - Make field `allocation_type` invisible if there is no active accrual plan in the database. -Accruals -Add an "archive" in the action menu of the accrual plan. -Show Employee button in the form view of the Accrual Plan.  -Renamed stress day into the mandatory days. -Renamed string of the menu Approval into the Management. -Remove two legends in the time-off Dashboard - Public Holiday - Mandatory Day task-3084232 closes odoo/odoo#116472 Related: odoo/enterprise#40576 Related: odoo/upgrade#4472 Signed-off-by: Sofie Gvaladze (sgv) --- addons/hr_holidays/__manifest__.py | 2 +- addons/hr_holidays/data/hr_holidays_demo.xml | 4 +- addons/hr_holidays/models/__init__.py | 2 +- addons/hr_holidays/models/hr_employee.py | 24 +++++------ addons/hr_holidays/models/hr_leave.py | 16 ++++---- .../models/hr_leave_accrual_plan.py | 1 + .../hr_holidays/models/hr_leave_allocation.py | 16 +++++++- ...tress_day.py => hr_leave_mandatory_day.py} | 6 +-- .../security/hr_holidays_security.xml | 6 +-- .../hr_holidays/security/ir.model.access.csv | 4 +- .../static/src/dashboard/time_off_card.xml | 2 +- .../static/src/tours/hr_holidays_tour.js | 2 +- .../views/calendar/calendar_controller.xml | 3 +- .../src/views/calendar/calendar_model.js | 12 +++--- .../src/views/calendar/calendar_renderer.scss | 2 +- .../common/calendar_common_renderer.js | 6 +-- .../filter_panel/calendar_filter_panel.js | 10 ++--- .../filter_panel/calendar_filter_panel.scss | 4 +- .../filter_panel/calendar_filter_panel.xml | 14 +++---- .../calendar/year/calendar_year_popover.js | 2 +- .../calendar/year/calendar_year_popover.xml | 2 +- .../calendar/year/calendar_year_renderer.js | 28 ++++++------- addons/hr_holidays/static/src/views/hooks.js | 12 +++--- addons/hr_holidays/tests/__init__.py | 2 +- .../hr_holidays/tests/test_access_rights.py | 4 +- ..._stress_days.py => test_mandatory_days.py} | 40 +++++++++---------- .../hr_holidays/views/hr_holidays_views.xml | 16 ++++---- .../views/hr_leave_accrual_views.xml | 11 +++-- .../views/hr_leave_allocation_views.xml | 31 ++++++++++---- ...s.xml => hr_leave_mandatory_day_views.xml} | 31 +++++++------- addons/hr_holidays/views/hr_leave_views.xml | 23 ++++++++++- .../views/resource_calendar_leaves_views.xml | 4 +- 32 files changed, 197 insertions(+), 145 deletions(-) rename addons/hr_holidays/models/{hr_leave_stress_day.py => hr_leave_mandatory_day.py} (89%) rename addons/hr_holidays/tests/{test_stress_days.py => test_mandatory_days.py} (86%) rename addons/hr_holidays/views/{hr_leave_stress_day_views.xml => hr_leave_mandatory_day_views.xml} (63%) diff --git a/addons/hr_holidays/__manifest__.py b/addons/hr_holidays/__manifest__.py index 6a335eed202..a3030898750 100644 --- a/addons/hr_holidays/__manifest__.py +++ b/addons/hr_holidays/__manifest__.py @@ -40,7 +40,7 @@ A synchronization with an internal agenda (Meetings of the CRM module) is also p 'views/hr_leave_type_views.xml', 'views/hr_leave_allocation_views.xml', 'views/hr_leave_accrual_views.xml', - 'views/hr_leave_stress_day_views.xml', + 'views/hr_leave_mandatory_day_views.xml', 'views/mail_activity_views.xml', 'wizard/hr_holidays_cancel_leave_views.xml', diff --git a/addons/hr_holidays/data/hr_holidays_demo.xml b/addons/hr_holidays/data/hr_holidays_demo.xml index ac5ebc03c17..91bc77c3703 100644 --- a/addons/hr_holidays/data/hr_holidays_demo.xml +++ b/addons/hr_holidays/data/hr_holidays_demo.xml @@ -478,8 +478,8 @@ - - + + Company Celebration diff --git a/addons/hr_holidays/models/__init__.py b/addons/hr_holidays/models/__init__.py index 0ebc25fcf80..55a0d612635 100644 --- a/addons/hr_holidays/models/__init__.py +++ b/addons/hr_holidays/models/__init__.py @@ -10,7 +10,7 @@ from . import hr_leave_allocation from . import hr_leave_type from . import hr_leave_accrual_plan_level from . import hr_leave_accrual_plan -from . import hr_leave_stress_day +from . import hr_leave_mandatory_day from . import mail_message_subtype from . import res_partner from . import res_users diff --git a/addons/hr_holidays/models/hr_employee.py b/addons/hr_holidays/models/hr_employee.py index 27e2ae69bc1..a90b152c020 100644 --- a/addons/hr_holidays/models/hr_employee.py +++ b/addons/hr_holidays/models/hr_employee.py @@ -273,23 +273,23 @@ class HrEmployee(models.Model): def _is_leave_user(self): return self == self.env.user.employee_id and self.user_has_groups('hr_holidays.group_hr_holidays_user') - def get_stress_days(self, start_date, end_date): + def get_mandatory_days(self, start_date, end_date): all_days = {} self = self or self.env.user.employee_id - stress_days = self._get_stress_days(start_date, end_date) - for stress_day in stress_days: - num_days = (stress_day.end_date - stress_day.start_date).days + mandatory_days = self._get_mandatory_days(start_date, end_date) + for mandatory_day in mandatory_days: + num_days = (mandatory_day.end_date - mandatory_day.start_date).days for d in range(num_days + 1): - all_days[str(stress_day.start_date + relativedelta(days=d))] = stress_day.color + all_days[str(mandatory_day.start_date + relativedelta(days=d))] = mandatory_day.color return all_days @api.model def get_special_days_data(self, date_start, date_end): return { - 'stressDays': self.get_stress_days_data(date_start, date_end), + 'mandatoryDays': self.get_mandatory_days_data(date_start, date_end), 'bankHolidays': self.get_public_holidays_data(date_start, date_end), } @@ -328,9 +328,9 @@ class HrEmployee(models.Model): return self.env['resource.calendar.leaves'].search(domain) @api.model - def get_stress_days_data(self, date_start, date_end): + def get_mandatory_days_data(self, date_start, date_end): self = self._get_contextual_employee() - stress_days = self._get_stress_days(date_start, date_end).sorted('start_date') + mandatory_days = self._get_mandatory_days(date_start, date_end).sorted('start_date') return list(map(lambda sd: { 'id': -sd.id, 'colorIndex': sd.color, @@ -340,16 +340,16 @@ class HrEmployee(models.Model): 'start': datetime.datetime.combine(sd.start_date, datetime.datetime.min.time()).isoformat(), 'startType': "datetime", 'title': sd.name, - }, stress_days)) + }, mandatory_days)) - def _get_stress_days(self, start_date, end_date): + def _get_mandatory_days(self, start_date, end_date): domain = [ ('start_date', '<=', end_date), ('end_date', '>=', start_date), ('company_id', 'in', self.env.companies.ids), ] - # a user with hr_holidays permissions will be able to see all stress days from his calendar + # a user with hr_holidays permissions will be able to see all mandatory days from his calendar if not self._is_leave_user(): domain += [ '|', @@ -365,4 +365,4 @@ class HrEmployee(models.Model): else: domain += [('department_ids', '=', False)] - return self.env['hr.leave.stress.day'].search(domain) + return self.env['hr.leave.mandatory.day'].search(domain) diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index a3b6ecc5fd9..339fe5000c6 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -300,7 +300,7 @@ class HolidaysRequest(models.Model): # view is_hatched = fields.Boolean('Hatched', compute='_compute_is_hatched') is_striked = fields.Boolean('Striked', compute='_compute_is_hatched') - has_stress_day = fields.Boolean(compute='_compute_has_stress_day') + has_mandatory_day = fields.Boolean(compute='_compute_has_mandatory_day') _sql_constraints = [ ('type_value', @@ -473,10 +473,10 @@ class HolidaysRequest(models.Model): holiday.department_id = False @api.depends('date_from', 'date_to', 'holiday_status_id') - def _compute_has_stress_day(self): + def _compute_has_mandatory_day(self): date_from, date_to = min(self.mapped('date_from')), max(self.mapped('date_to')) if date_from and date_to: - stress_days = self.employee_id._get_stress_days( + mandatory_days = self.employee_id._get_mandatory_days( date_from.date(), date_to.date()) @@ -491,9 +491,9 @@ class HolidaysRequest(models.Model): if leave.holiday_status_id.company_id: domain += [('company_id', '=', leave.holiday_status_id.company_id.id)] - leave.has_stress_day = leave.date_from and leave.date_to and stress_days.filtered_domain(domain) + leave.has_mandatory_day = leave.date_from and leave.date_to and mandatory_days.filtered_domain(domain) else: - self.has_stress_day = False + self.has_mandatory_day = False @api.depends('date_from', 'date_to', 'employee_id') def _compute_number_of_days(self): @@ -862,10 +862,10 @@ class HolidaysRequest(models.Model): self.message_subscribe(partner_ids=employee.user_id.partner_id.ids) @api.constrains('date_from', 'date_to') - def _check_stress_day(self): + def _check_mandatory_day(self): is_leave_user = self.user_has_groups('hr_holidays.group_hr_holidays_user') - if not is_leave_user and any(leave.has_stress_day for leave in self): - raise ValidationError(_('You are not allowed to request a time off on a Stress Day.')) + if not is_leave_user and any(leave.has_mandatory_day for leave in self): + raise ValidationError(_('You are not allowed to request a time off on a Mandatory Day.')) def _check_double_validation_rules(self, employees, state): if self.user_has_groups('hr_holidays.group_hr_holidays_manager'): diff --git a/addons/hr_holidays/models/hr_leave_accrual_plan.py b/addons/hr_holidays/models/hr_leave_accrual_plan.py index 372ca9ed24b..a4568b48dd8 100644 --- a/addons/hr_holidays/models/hr_leave_accrual_plan.py +++ b/addons/hr_holidays/models/hr_leave_accrual_plan.py @@ -8,6 +8,7 @@ class AccrualPlan(models.Model): _name = "hr.leave.accrual.plan" _description = "Accrual Plan" + active = fields.Boolean(default=True) name = fields.Char('Name', required=True) time_off_type_id = fields.Many2one('hr.leave.type', string="Time Off Type", check_company=True, diff --git a/addons/hr_holidays/models/hr_leave_allocation.py b/addons/hr_holidays/models/hr_leave_allocation.py index a9a35984f65..2a75c88164b 100644 --- a/addons/hr_holidays/models/hr_leave_allocation.py +++ b/addons/hr_holidays/models/hr_leave_allocation.py @@ -9,7 +9,7 @@ import logging from datetime import datetime, time from dateutil.relativedelta import relativedelta -from odoo import api, fields, models +from odoo import api, fields, models, _ from odoo.addons.resource.models.utils import HOURS_PER_DAY from odoo.addons.hr_holidays.models.hr_leave import get_employee_from_context from odoo.exceptions import AccessError, UserError, ValidationError @@ -136,6 +136,7 @@ class HolidaysAllocation(models.Model): max_leaves = fields.Float(compute='_compute_leaves') leaves_taken = fields.Float(compute='_compute_leaves', string='Time off Taken') taken_leave_ids = fields.One2many('hr.leave', 'holiday_allocation_id', domain="[('state', 'in', ['confirm', 'validate1', 'validate'])]") + has_accrual_plan = fields.Boolean(compute='_compute_has_accrual_plan', string='Accrual Plan Available') _sql_constraints = [ ('type_value', @@ -168,7 +169,14 @@ class HolidaysAllocation(models.Model): for allocation in self: if is_officer or allocation.employee_id.user_id == self.env.user or allocation.employee_id.leave_manager_id == self.env.user: - allocation.name = allocation.sudo().private_name + title = allocation.sudo().private_name + if allocation.env.context.get('is_employee_allocation'): + allocation_duration = allocation.number_of_days_display if allocation.type_request_unit != 'hour' else allocation.number_of_hours_display + title = _(" %s Allocation Request ( %s %s)" % ( + allocation.holiday_status_id.name, + allocation_duration, + allocation.type_request_unit)) + allocation.name = title else: allocation.name = '*****' @@ -188,6 +196,10 @@ class HolidaysAllocation(models.Model): allocations = self.sudo().search(domain) return [('id', 'in', allocations.ids)] + @api.depends('accrual_plan_id') + def _compute_has_accrual_plan(self): + self.has_accrual_plan = bool(self.env['hr.leave.accrual.plan'].sudo().search_count([('active', '=', True)])) + @api.depends('name', 'date_from', 'date_to') def _compute_description_validity(self): for allocation in self: diff --git a/addons/hr_holidays/models/hr_leave_stress_day.py b/addons/hr_holidays/models/hr_leave_mandatory_day.py similarity index 89% rename from addons/hr_holidays/models/hr_leave_stress_day.py rename to addons/hr_holidays/models/hr_leave_mandatory_day.py index 091a3d5c47d..fe8f067f536 100644 --- a/addons/hr_holidays/models/hr_leave_stress_day.py +++ b/addons/hr_holidays/models/hr_leave_mandatory_day.py @@ -4,9 +4,9 @@ from random import randint from odoo import fields, models -class StressDay(models.Model): - _name = 'hr.leave.stress.day' - _description = 'Stress Day' +class MandatoryDay(models.Model): + _name = 'hr.leave.mandatory.day' + _description = 'Mandatory Day' _order = 'start_date desc, end_date desc' name = fields.Char(required=True) diff --git a/addons/hr_holidays/security/hr_holidays_security.xml b/addons/hr_holidays/security/hr_holidays_security.xml index e3b10ecbec7..d9628c3fc8d 100644 --- a/addons/hr_holidays/security/hr_holidays_security.xml +++ b/addons/hr_holidays/security/hr_holidays_security.xml @@ -249,9 +249,9 @@ ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] - - Stress Day: multi company rule - + + Mandatory Day: multi company rule + ['|', ('company_id', '=', False), ('company_id', 'in', company_ids)] diff --git a/addons/hr_holidays/security/ir.model.access.csv b/addons/hr_holidays/security/ir.model.access.csv index f6979d41243..4f032e847ba 100644 --- a/addons/hr_holidays/security/ir.model.access.csv +++ b/addons/hr_holidays/security/ir.model.access.csv @@ -22,5 +22,5 @@ access_hr_leave_accrual_level_user,hr.leave.accrual.level.user,model_hr_leave_ac access_hr_leave_accrual_plan_manager,hr.leave.accrual.plan.manager,model_hr_leave_accrual_plan,hr_holidays.group_hr_holidays_manager,1,1,1,1 access_hr_leave_accrual_level_manager,hr.leave.accrual.level.manager,model_hr_leave_accrual_level,hr_holidays.group_hr_holidays_manager,1,1,1,1 access_hr_holidays_cancel_leave,access_hr_holidays_cancel_leave,hr_holidays.model_hr_holidays_cancel_leave,base.group_user,1,1,1,1 -access_hr_leave_stress_day_user,access_hr_holidays_stress_day_user,hr_holidays.model_hr_leave_stress_day,base.group_user,1,0,0,0 -access_hr_leave_stress_day_manager,access_hr_holidays_stress_day_manager,hr_holidays.model_hr_leave_stress_day,hr_holidays.group_hr_holidays_manager,1,1,1,1 +access_hr_leave_mandatory_day_user,access_hr_holidays_mandatory_day_user,hr_holidays.model_hr_leave_mandatory_day,base.group_user,1,0,0,0 +access_hr_leave_mandatory_day_manager,access_hr_holidays_mandatory_day_manager,hr_holidays.model_hr_leave_mandatory_day,hr_holidays.group_hr_holidays_manager,1,1,1,1 diff --git a/addons/hr_holidays/static/src/dashboard/time_off_card.xml b/addons/hr_holidays/static/src/dashboard/time_off_card.xml index d7c419680d3..877bf23b63f 100644 --- a/addons/hr_holidays/static/src/dashboard/time_off_card.xml +++ b/addons/hr_holidays/static/src/dashboard/time_off_card.xml @@ -63,7 +63,7 @@
  • Allocated:
  • Approved:
  • Planned:
  • -
  • Left:
  • +
  • Available:
  • diff --git a/addons/hr_holidays/static/src/tours/hr_holidays_tour.js b/addons/hr_holidays/static/src/tours/hr_holidays_tour.js index 49bacd06d05..d70d15c436b 100644 --- a/addons/hr_holidays/static/src/tours/hr_holidays_tour.js +++ b/addons/hr_holidays/static/src/tours/hr_holidays_tour.js @@ -62,7 +62,7 @@ registry.category("web_tour.tours").add('hr_holidays_tour', { position: 'bottom', }, { - trigger: 'button[data-menu-xmlid="hr_holidays.menu_hr_holidays_approvals"]', + trigger: 'button[data-menu-xmlid="hr_holidays.menu_hr_holidays_management"]', content: _t("Let's go validate it"), position: 'bottom' }, diff --git a/addons/hr_holidays/static/src/views/calendar/calendar_controller.xml b/addons/hr_holidays/static/src/views/calendar/calendar_controller.xml index 307458f8b4e..788cf55816a 100644 --- a/addons/hr_holidays/static/src/views/calendar/calendar_controller.xml +++ b/addons/hr_holidays/static/src/views/calendar/calendar_controller.xml @@ -11,7 +11,8 @@ diff --git a/addons/hr_holidays/static/src/views/calendar/calendar_model.js b/addons/hr_holidays/static/src/views/calendar/calendar_model.js index a3c3c138920..ad218d1b7c9 100644 --- a/addons/hr_holidays/static/src/views/calendar/calendar_model.js +++ b/addons/hr_holidays/static/src/views/calendar/calendar_model.js @@ -7,7 +7,7 @@ export class TimeOffCalendarModel extends CalendarModel { setup(params, services) { super.setup(params, services); - this.data.stressDays = {}; + this.data.mandatoryDays = {}; if (this.env.isSmall) { this.meta.scale = 'month'; } @@ -46,7 +46,7 @@ export class TimeOffCalendarModel extends CalendarModel { async updateData(data) { await super.updateData(data); - data.stressDays = await this.fetchStressDays(data); + data.mandatoryDays = await this.fetchMandatoryDays(data); } /** @@ -64,16 +64,16 @@ export class TimeOffCalendarModel extends CalendarModel { }); } - async fetchStressDays(data) { - return this.orm.call("hr.employee", "get_stress_days", [ + async fetchMandatoryDays(data) { + return this.orm.call("hr.employee", "get_mandatory_days", [ this.employeeId, serializeDate(data.range.start, "datetime"), serializeDate(data.range.end, "datetime"), ]); } - get stressDays() { - return this.data.stressDays; + get mandatoryDays() { + return this.data.mandatoryDays; } get employeeId() { diff --git a/addons/hr_holidays/static/src/views/calendar/calendar_renderer.scss b/addons/hr_holidays/static/src/views/calendar/calendar_renderer.scss index 3fb3dd55048..688dca438d9 100644 --- a/addons/hr_holidays/static/src/views/calendar/calendar_renderer.scss +++ b/addons/hr_holidays/static/src/views/calendar/calendar_renderer.scss @@ -4,7 +4,7 @@ @for $size from 1 through length($o-colors) { .o_calendar_widget { - .hr_stress_day_top_#{$size - 1}:not(.fc-disabled-day) { + .hr_mandatory_day_top_#{$size - 1}:not(.fc-disabled-day) { .fc-day-number { color: nth($o-colors, $size) !important; font-weight: 600; diff --git a/addons/hr_holidays/static/src/views/calendar/common/calendar_common_renderer.js b/addons/hr_holidays/static/src/views/calendar/common/calendar_common_renderer.js index 6a51f4fbc72..1c8cc624ab6 100644 --- a/addons/hr_holidays/static/src/views/calendar/common/calendar_common_renderer.js +++ b/addons/hr_holidays/static/src/views/calendar/common/calendar_common_renderer.js @@ -2,19 +2,19 @@ import { CalendarCommonRenderer } from '@web/views/calendar/calendar_common/calendar_common_renderer'; -import { useStressDays } from '../../hooks'; +import { useMandatoryDays } from '../../hooks'; import { TimeOffCalendarCommonPopover } from './calendar_common_popover'; export class TimeOffCalendarCommonRenderer extends CalendarCommonRenderer { setup() { super.setup(); - this.stressDays = useStressDays(this.props); + this.mandatoryDays = useMandatoryDays(this.props); } onDayRender(info) { super.onDayRender(info); - this.stressDays(info); + this.mandatoryDays(info); } } TimeOffCalendarCommonRenderer.components = { diff --git a/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.js b/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.js index 66f27f2efe8..69cd47546f8 100644 --- a/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.js +++ b/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.js @@ -17,7 +17,7 @@ export class TimeOffCalendarFilterPanel extends CalendarFilterPanel { this.getFormattedDateSpan = getFormattedDateSpan; this.leaveState = useState({ holidays: [], - stressDays: [], + mandatoryDays: [], bankHolidays: [], }); @@ -45,12 +45,12 @@ export class TimeOffCalendarFilterPanel extends CalendarFilterPanel { bankHoliday.start = luxon.DateTime.fromISO(bankHoliday.start) bankHoliday.end = luxon.DateTime.fromISO(bankHoliday.end) }); - specialDays['stressDays'].forEach(stressDay => { - stressDay.start = luxon.DateTime.fromISO(stressDay.start) - stressDay.end = luxon.DateTime.fromISO(stressDay.end) + specialDays['mandatoryDays'].forEach(mandatoryDay => { + mandatoryDay.start = luxon.DateTime.fromISO(mandatoryDay.start) + mandatoryDay.end = luxon.DateTime.fromISO(mandatoryDay.end) }); this.leaveState.bankHolidays = specialDays['bankHolidays']; - this.leaveState.stressDays = specialDays['stressDays']; + this.leaveState.mandatoryDays = specialDays['mandatoryDays']; } async loadFilterData() { diff --git a/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.scss b/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.scss index b54714048b8..faabc002756 100644 --- a/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.scss +++ b/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.scss @@ -31,13 +31,13 @@ background-color: $gray-200; } - &_stressday { + &_mandatoryday { font-weight: 600; } } @for $size from 1 through length($o-colors) { - .hr_stress_day_#{$size - 1}:not(.fc-disabled-day) { + .hr_mandatory_day_#{$size - 1}:not(.fc-disabled-day) { color: nth($o-colors, $size) !important; } } diff --git a/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.xml b/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.xml index 5b61787c1c0..09fcc648a5c 100644 --- a/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.xml +++ b/addons/hr_holidays/static/src/views/calendar/filter_panel/calendar_filter_panel.xml @@ -10,18 +10,16 @@ Validated To Approve Refused - 13 Public Holiday - 13 Stress Day -
    -
    Stress Days
    +
    +
    Mandatory Days
      -
    • +
    • - : + t-esc="getFormattedDateSpan(mandatoryDay.start, mandatoryDay.end)" + t-att-class="'hr_mandatory_day_'+mandatoryDay.colorIndex"/> + :
    diff --git a/addons/hr_holidays/static/src/views/calendar/year/calendar_year_popover.js b/addons/hr_holidays/static/src/views/calendar/year/calendar_year_popover.js index 0349a89a944..d4772bc7911 100644 --- a/addons/hr_holidays/static/src/views/calendar/year/calendar_year_popover.js +++ b/addons/hr_holidays/static/src/views/calendar/year/calendar_year_popover.js @@ -9,5 +9,5 @@ TimeOffCalendarYearPopover.components = { Dialog }; TimeOffCalendarYearPopover.template = "web.CalendarYearPopover"; TimeOffCalendarYearPopover.subTemplates = { ...CalendarYearPopover.subTemplates, - body: "hr_holidays.StressDayCalendarYearPopover.body", + body: "hr_holidays.MandatoryDayCalendarYearPopover.body", }; diff --git a/addons/hr_holidays/static/src/views/calendar/year/calendar_year_popover.xml b/addons/hr_holidays/static/src/views/calendar/year/calendar_year_popover.xml index eb47650baec..a4be527e96d 100644 --- a/addons/hr_holidays/static/src/views/calendar/year/calendar_year_popover.xml +++ b/addons/hr_holidays/static/src/views/calendar/year/calendar_year_popover.xml @@ -1,6 +1,6 @@ - +
    diff --git a/addons/hr_holidays/static/src/views/calendar/year/calendar_year_renderer.js b/addons/hr_holidays/static/src/views/calendar/year/calendar_year_renderer.js index b30211269aa..7a4ead2aeac 100644 --- a/addons/hr_holidays/static/src/views/calendar/year/calendar_year_renderer.js +++ b/addons/hr_holidays/static/src/views/calendar/year/calendar_year_renderer.js @@ -3,7 +3,7 @@ import { CalendarYearRenderer } from '@web/views/calendar/calendar_year/calendar_year_renderer'; import { useService } from "@web/core/utils/hooks"; -import { useStressDays } from '../../hooks'; +import { useMandatoryDays } from '../../hooks'; import { useCalendarPopover } from '@web/views/calendar/hooks'; import { TimeOffCalendarYearPopover } from './calendar_year_popover'; @@ -13,9 +13,9 @@ export class TimeOffCalendarYearRenderer extends CalendarYearRenderer { setup() { super.setup(); this.orm = useService("orm"); - this.stressDays = useStressDays(this.props); - this.stressDaysList = []; - this.stressDayPopover = useCalendarPopover(TimeOffCalendarYearPopover); + this.mandatoryDays = useMandatoryDays(this.props); + this.mandatoryDaysList = []; + this.mandatoryDayPopover = useCalendarPopover(TimeOffCalendarYearPopover); useEffect((el) => { for (const week of el) { @@ -41,23 +41,23 @@ export class TimeOffCalendarYearRenderer extends CalendarYearRenderer { /** @override **/ async onDateClick(info) { - const is_stress_day = [...info.dayEl.classList].some(elClass => elClass.startsWith('hr_stress_day_')) - this.stressDayPopover.close(); - if (is_stress_day && !this.env.isSmall) { + const is_mandatory_day = [...info.dayEl.classList].some(elClass => elClass.startsWith('hr_mandatory_day_')) + this.mandatoryDayPopover.close(); + if (is_mandatory_day && !this.env.isSmall) { this.popover.close(); const date = luxon.DateTime.fromISO(info.dateStr); const target = info.dayEl; - const stress_days_data = await this.orm.call("hr.employee", "get_stress_days_data", [date, date]); - stress_days_data.forEach(stress_day_data => { - stress_day_data['start'] = luxon.DateTime.fromISO(stress_day_data['start']) - stress_day_data['end'] = luxon.DateTime.fromISO(stress_day_data['end']) + const mandatory_days_data = await this.orm.call("hr.employee", "get_mandatory_days_data", [date, date]); + mandatory_days_data.forEach(mandatory_day_data => { + mandatory_day_data['start'] = luxon.DateTime.fromISO(mandatory_day_data['start']) + mandatory_day_data['end'] = luxon.DateTime.fromISO(mandatory_day_data['end']) }); const records = Object.values(this.props.model.records).filter((r) => luxon.Interval.fromDateTimes(r.start.startOf("day"), r.end.endOf("day")).contains(date) ); const props = this.getPopoverProps(date, records) - props['records'] = stress_days_data.concat(props['records']) - this.stressDayPopover.open(target, props, "o_cw_popover"); + props['records'] = mandatory_days_data.concat(props['records']) + this.mandatoryDayPopover.open(target, props, "o_cw_popover"); } else { super.onDateClick(info); @@ -66,6 +66,6 @@ export class TimeOffCalendarYearRenderer extends CalendarYearRenderer { onDayRender(info) { super.onDayRender(info); - this.stressDaysList = this.stressDays(info); + this.mandatoryDaysList = this.mandatoryDays(info); } } diff --git a/addons/hr_holidays/static/src/views/hooks.js b/addons/hr_holidays/static/src/views/hooks.js index 1bb18204b54..2ee275137b5 100644 --- a/addons/hr_holidays/static/src/views/hooks.js +++ b/addons/hr_holidays/static/src/views/hooks.js @@ -4,21 +4,21 @@ import { useService } from "@web/core/utils/hooks"; const { useEnv } = owl; -export function useStressDays(props) { +export function useMandatoryDays(props) { return (info) => { const date = luxon.DateTime.fromJSDate(info.date).toISODate(); - const stressDay = props.model.stressDays[date]; - if (stressDay) { + const mandatoryDay = props.model.mandatoryDays[date]; + if (mandatoryDay) { const dayNumberElTop = info.view.el.querySelector(`.fc-day-top[data-date="${info.el.dataset.date }"]`) const dayNumberEl = info.view.el.querySelector(`.fc-day[data-date="${info.el.dataset.date }"]`) if (dayNumberElTop) { - dayNumberElTop.classList.add(`hr_stress_day_top_${stressDay}`); + dayNumberElTop.classList.add(`hr_mandatory_day_top_${mandatoryDay}`); } if (dayNumberEl) { - dayNumberEl.classList.add(`hr_stress_day_${stressDay}`); + dayNumberEl.classList.add(`hr_mandatory_day_${mandatoryDay}`); } } - return props.model.stressDays; + return props.model.mandatoryDays; } } diff --git a/addons/hr_holidays/tests/__init__.py b/addons/hr_holidays/tests/__init__.py index e9c0bc4e37a..bdb693bf38a 100644 --- a/addons/hr_holidays/tests/__init__.py +++ b/addons/hr_holidays/tests/__init__.py @@ -14,7 +14,7 @@ from . import test_leave_requests from . import test_out_of_office from . import test_company_leave from . import test_res_partner -from . import test_stress_days +from . import test_mandatory_days from . import test_global_leaves from . import test_uninstall from . import test_holidays_calendar diff --git a/addons/hr_holidays/tests/test_access_rights.py b/addons/hr_holidays/tests/test_access_rights.py index 7db64df1838..d3a43b59f13 100644 --- a/addons/hr_holidays/tests/test_access_rights.py +++ b/addons/hr_holidays/tests/test_access_rights.py @@ -71,8 +71,8 @@ class TestHrHolidaysAccessRightsCommon(TestHrHolidaysCommon): ] # Here we only test access rights, prevent any conflict with - # existing stress days - they are tested someplace else. - cls.env['hr.leave.stress.day'].search([]).unlink() + # existing mandatory days - they are tested someplace else. + cls.env['hr.leave.mandatory.day'].search([]).unlink() def request_leave(self, user_id, date_from, number_of_days, values=None): values = dict(values or {}, **{ diff --git a/addons/hr_holidays/tests/test_stress_days.py b/addons/hr_holidays/tests/test_mandatory_days.py similarity index 86% rename from addons/hr_holidays/tests/test_stress_days.py rename to addons/hr_holidays/tests/test_mandatory_days.py index 410c24af2c3..152b7144399 100644 --- a/addons/hr_holidays/tests/test_stress_days.py +++ b/addons/hr_holidays/tests/test_mandatory_days.py @@ -11,7 +11,7 @@ from odoo.exceptions import ValidationError @tests.tagged('access_rights', 'post_install', '-at_install') -class TestHrLeaveStressDays(TransactionCase): +class TestHrLeaveMandatoryDays(TransactionCase): @classmethod def setUpClass(cls): super().setUpClass() @@ -47,7 +47,7 @@ class TestHrLeaveStressDays(TransactionCase): 'company_id': cls.company.id, }) - cls.stress_day = cls.env['hr.leave.stress.day'].create({ + cls.mandatory_day = cls.env['hr.leave.mandatory.day'].create({ 'name': 'Super Event', 'company_id': cls.company.id, 'start_date': datetime(2021, 11, 2), @@ -55,7 +55,7 @@ class TestHrLeaveStressDays(TransactionCase): 'color': 1, 'resource_calendar_id': cls.default_calendar.id, }) - cls.stress_week = cls.env['hr.leave.stress.day'].create({ + cls.mandatory_week = cls.env['hr.leave.mandatory.day'].create({ 'name': 'Super Event End Of Week', 'company_id': cls.company.id, 'start_date': datetime(2021, 11, 8), @@ -65,8 +65,8 @@ class TestHrLeaveStressDays(TransactionCase): }) @freeze_time('2021-10-15') - def test_request_stress_days(self): - # An employee can request time off outside stress days + def test_request_mandatory_days(self): + # An employee can request time off outside mandatory days self.env['hr.leave'].with_user(self.employee_user.id).create({ 'name': 'coucou', 'holiday_status_id': self.leave_type.id, @@ -76,7 +76,7 @@ class TestHrLeaveStressDays(TransactionCase): 'number_of_days': 1, }) - # Taking a time off during a Stress Day is not allowed for a simple employee... + # Taking a time off during a Mandatory Day is not allowed for a simple employee... with self.assertRaises(ValidationError): self.env['hr.leave'].with_user(self.employee_user.id).create({ 'name': 'coucou', @@ -108,28 +108,28 @@ class TestHrLeaveStressDays(TransactionCase): }) @freeze_time('2021-10-15') - def test_get_stress_days(self): - stress_days = self.employee_emp.get_stress_days('2021-11-01', '2021-11-30') + def test_get_mandatory_days(self): + mandatory_days = self.employee_emp.get_mandatory_days('2021-11-01', '2021-11-30') - # Stress Days spanning multiple days should be split in single days + # Mandatory Days spanning multiple days should be split in single days expected_data = {'2021-11-02': 1, '2021-11-08': 2, '2021-11-09': 2, '2021-11-10': 2, '2021-11-11': 2, '2021-11-12': 2} - self.assertEqual(len(stress_days), len(expected_data)) + self.assertEqual(len(mandatory_days), len(expected_data)) for day, color in expected_data.items(): - self.assertTrue(day in stress_days) - self.assertEqual(color, stress_days[day]) + self.assertTrue(day in mandatory_days) + self.assertEqual(color, mandatory_days[day]) with self.assertRaises(ValidationError), Form(self.env['hr.leave'].with_user(self.employee_user.id).with_context(default_employee_id=self.employee_emp.id)) as leave_form: leave_form.holiday_status_id = self.leave_type leave_form.request_date_from = datetime(2021, 11, 1) leave_form.request_date_to = datetime(2021, 11, 1) - self.assertFalse(leave_form.has_stress_day) + self.assertFalse(leave_form.has_mandatory_day) leave_form.request_date_to = datetime(2021, 11, 5) - self.assertTrue(leave_form.has_stress_day) + self.assertTrue(leave_form.has_mandatory_day) @freeze_time('2021-10-15') - def test_department_stress_days(self): + def test_department_mandatory_days(self): production_department = self.env['hr.department'].create({ 'name': 'Production Department', 'company_id': self.company.id, @@ -149,8 +149,8 @@ class TestHrLeaveStressDays(TransactionCase): 'department_id': post_production_department.id }) - # Create one stress day for each department - self.env['hr.leave.stress.day'].create({ + # Create one mandatory day for each department + self.env['hr.leave.mandatory.day'].create({ 'name': 'Last Rush Before Launch (production)', 'company_id': self.company.id, 'start_date': datetime(2021, 11, 3), @@ -159,7 +159,7 @@ class TestHrLeaveStressDays(TransactionCase): 'resource_calendar_id': self.default_calendar.id, 'department_ids': [production_department.id], }) - self.env['hr.leave.stress.day'].create({ + self.env['hr.leave.mandatory.day'].create({ 'name': 'Last Rush Before Launch (post-production)', 'company_id': self.company.id, 'start_date': datetime(2021, 11, 4), @@ -168,7 +168,7 @@ class TestHrLeaveStressDays(TransactionCase): 'resource_calendar_id': self.default_calendar.id, 'department_ids': [post_production_department.id], }) - self.env['hr.leave.stress.day'].create({ + self.env['hr.leave.mandatory.day'].create({ 'name': 'Last Rush Before Launch (deployment)', 'company_id': self.company.id, 'start_date': datetime(2021, 11, 5), @@ -178,7 +178,7 @@ class TestHrLeaveStressDays(TransactionCase): 'department_ids': [deployment_department.id], }) - # The employee should only be able to create a time off on stress days + # The employee should only be able to create a time off on mandatory days # that do not include his department with self.assertRaises(ValidationError): self.env['hr.leave'].with_user(self.employee_user.id).create({ diff --git a/addons/hr_holidays/views/hr_holidays_views.xml b/addons/hr_holidays/views/hr_holidays_views.xml index 8d729ec97ed..3eda688ca33 100644 --- a/addons/hr_holidays/views/hr_holidays_views.xml +++ b/addons/hr_holidays/views/hr_holidays_views.xml @@ -10,7 +10,7 @@ @@ -41,8 +41,8 @@ action="action_hr_holidays_dashboard"/> @@ -50,14 +50,14 @@ @@ -114,9 +114,9 @@ sequence="3"/> diff --git a/addons/hr_holidays/views/hr_leave_accrual_views.xml b/addons/hr_holidays/views/hr_leave_accrual_views.xml index a690ec84bc4..f27a12e74d8 100644 --- a/addons/hr_holidays/views/hr_leave_accrual_views.xml +++ b/addons/hr_holidays/views/hr_leave_accrual_views.xml @@ -25,7 +25,7 @@
    - - + + @@ -75,13 +75,15 @@ hr.leave.accrual.plan
    + -
    +
    + @@ -200,6 +202,7 @@ hr.leave.accrual.plan + diff --git a/addons/hr_holidays/views/hr_leave_allocation_views.xml b/addons/hr_holidays/views/hr_leave_allocation_views.xml index 70e240531f8..aa0f16f2038 100644 --- a/addons/hr_holidays/views/hr_leave_allocation_views.xml +++ b/addons/hr_holidays/views/hr_leave_allocation_views.xml @@ -12,10 +12,12 @@ - @@ -75,15 +77,16 @@
    -

    +

    + + attrs="{'readonly': ['|', ('is_officer', '=', False), ('state', 'not in', ('draft', 'confirm'))], 'invisible': [('has_accrual_plan', '=', False)]}"/>
    @@ -100,7 +103,7 @@
    -
    @@ -247,7 +250,7 @@ - + @@ -309,6 +312,18 @@ 1 + + 1 + + + 1 + + + Archived Time Off Type + + + 1 + @@ -416,7 +431,7 @@ Employees request allocations to Time Off Officers (e.g. recuperation days).

    - {} + {'search_default_year': 1 , 'is_employee_allocation': True} [('employee_id.user_id', '=', uid)] diff --git a/addons/hr_holidays/views/hr_leave_stress_day_views.xml b/addons/hr_holidays/views/hr_leave_mandatory_day_views.xml similarity index 63% rename from addons/hr_holidays/views/hr_leave_stress_day_views.xml rename to addons/hr_holidays/views/hr_leave_mandatory_day_views.xml index aef11fcf4d8..cffca560f59 100644 --- a/addons/hr_holidays/views/hr_leave_stress_day_views.xml +++ b/addons/hr_holidays/views/hr_leave_mandatory_day_views.xml @@ -1,7 +1,7 @@ - - hr.leave.stress.day + + hr.leave.mandatory.day @@ -21,41 +21,44 @@ - - hr.leave.stress.day + + hr.leave.mandatory.day - + + - - - - hr.leave.stress.day + + hr.leave.mandatory.day - + + + + + - - Stress Days - hr.leave.stress.day + + Mandatory Days + hr.leave.mandatory.day tree,form - + {'search_default_filter_date': True} diff --git a/addons/hr_holidays/views/hr_leave_views.xml b/addons/hr_holidays/views/hr_leave_views.xml index 0716b8135ca..6fc2e899b5b 100644 --- a/addons/hr_holidays/views/hr_leave_views.xml +++ b/addons/hr_holidays/views/hr_leave_views.xml @@ -213,7 +213,7 @@ - +