From 2332624ca415668521b7ad323c2737dafb8a3374 Mon Sep 17 00:00:00 2001 From: sofiagvaladze Date: Mon, 27 Feb 2023 08:50:12 +0000 Subject: [PATCH] [IMP] hr_holidays: allow quick approval on dashboard Purpose: HR can view employee leave records from the calendar but can not approve, validate or refuse it from there. In case they want to make action, they have to go through menu < time off < approvals < time off < find the employee < find the requested time off < open it < approve. In this commit the action buttons are added on the dashboard. task - 3175495 closes odoo/odoo#116342 Signed-off-by: Kevin Baptiste --- addons/hr_holidays/models/hr_leave.py | 6 ++- .../src/views/calendar/calendar_controller.js | 1 + .../src/views/view_dialog/form_view_dialog.js | 40 +++++++++++++++---- .../views/view_dialog/form_view_dialog.xml | 8 +++- addons/hr_holidays/views/hr_leave_views.xml | 3 ++ 5 files changed, 48 insertions(+), 10 deletions(-) diff --git a/addons/hr_holidays/models/hr_leave.py b/addons/hr_holidays/models/hr_leave.py index a873d92e701..4b32abfef2e 100644 --- a/addons/hr_holidays/models/hr_leave.py +++ b/addons/hr_holidays/models/hr_leave.py @@ -1207,10 +1207,12 @@ class HolidaysRequest(models.Model): self.activity_update() return True - def action_approve(self): + def action_approve(self, check_state=True): # if validation_type == 'both': this method is the first approval approval # if validation_type != 'both': this method calls action_validate() below - if any(holiday.state != 'confirm' for holiday in self): + + # Do not check the state in case we are redirected from the dashboard + if check_state and any(holiday.state != 'confirm' for holiday in self): raise UserError(_('Time off request must be confirmed ("To Approve") in order to approve it.')) current_employee = self.env.user.employee_id diff --git a/addons/hr_holidays/static/src/views/calendar/calendar_controller.js b/addons/hr_holidays/static/src/views/calendar/calendar_controller.js index 218efb07c6c..40030311ec3 100644 --- a/addons/hr_holidays/static/src/views/calendar/calendar_controller.js +++ b/addons/hr_holidays/static/src/views/calendar/calendar_controller.js @@ -104,6 +104,7 @@ export class TimeOffCalendarController extends CalendarController { onRecordSaved: onDialogClosed, onRecordDeleted: (record) => this.deleteRecord(record), onLeaveCancelled: onDialogClosed, + size: 'md', }, { onClose: () => resolve() } ); diff --git a/addons/hr_holidays/static/src/views/view_dialog/form_view_dialog.js b/addons/hr_holidays/static/src/views/view_dialog/form_view_dialog.js index 695c6c37ada..4e1e04104a2 100644 --- a/addons/hr_holidays/static/src/views/view_dialog/form_view_dialog.js +++ b/addons/hr_holidays/static/src/views/view_dialog/form_view_dialog.js @@ -3,6 +3,7 @@ import { FormViewDialog } from "@web/views/view_dialogs/form_view_dialog"; import { registry } from '@web/core/registry'; +import { useService } from "@web/core/utils/hooks"; import { formView } from '@web/views/form/form_view'; import { FormController } from '@web/views/form/form_controller'; @@ -13,23 +14,43 @@ export class TimeOffDialogFormController extends FormController { setup() { super.setup(); this.leaveCancelWizard = useLeaveCancelWizard(); + this.orm = useService("orm"); + } + + get record() { + return this.model.root.data; + } + + async onClick(action) { + const args = (action === 'action_approve') ? [this.record.id, false] : [this.record.id]; + await this.orm.call("hr.leave", action, args); + this.props.onLeaveUpdated(); + } + + get canApprove() { + return !this.model.root.isNew && (this.record.can_approve && ['confirm', 'refuse',].includes(this.record.state)); + } + + get canValidate() { + return !this.model.root.isNew && (this.record.can_approve && this.record.state === 'validate1'); + } + + get canRefuse() { + return !this.model.root.isNew && (this.record.can_approve && this.record.state && ['confirm', 'validate1', 'validate'].includes(this.record.state)); } deleteRecord() { - const record = this.model.root.data - - this.props.onRecordDeleted(record) + this.props.onRecordDeleted(this.record) this.props.onCancelLeave(); - if (record.can_cancel) { - this.leaveCancelWizard(record.id, () => { + if (this.record.can_cancel) { + this.leaveCancelWizard(this.record.id, () => { this.props.onLeaveCancelled(); }); } } get canDelete() { - const record = this.model.root.data; - return !this.model.root.isNew && (record.can_cancel || record.state && !['validate', 'refuse'].includes(record.state)); + return !this.model.root.isNew && (this.record.can_cancel || this.record.state && !['validate', 'refuse'].includes(this.record.state)); } } @@ -38,6 +59,7 @@ TimeOffDialogFormController.props = { onCancelLeave: Function, onRecordDeleted: Function, onLeaveCancelled: Function, + onLeaveUpdated: Function, } registry.category('views').add('timeoff_dialog_form', { @@ -56,6 +78,10 @@ export class TimeOffFormViewDialog extends FormViewDialog { onCancelLeave: () => { this.props.close(); }, + onLeaveUpdated: () => { + this.props.onRecordSaved(); + this.props.close(); + }, onRecordDeleted: (record) => { this.props.onRecordDeleted(record) }, diff --git a/addons/hr_holidays/static/src/views/view_dialog/form_view_dialog.xml b/addons/hr_holidays/static/src/views/view_dialog/form_view_dialog.xml index 700e15d56b0..61fd9127a47 100644 --- a/addons/hr_holidays/static/src/views/view_dialog/form_view_dialog.xml +++ b/addons/hr_holidays/static/src/views/view_dialog/form_view_dialog.xml @@ -9,6 +9,12 @@ + +
+ + + +
+ - diff --git a/addons/hr_holidays/views/hr_leave_views.xml b/addons/hr_holidays/views/hr_leave_views.xml index 2394ed8ca0d..8574ee65fff 100644 --- a/addons/hr_holidays/views/hr_leave_views.xml +++ b/addons/hr_holidays/views/hr_leave_views.xml @@ -353,6 +353,9 @@ 5 + + +