From 2dbf95cb9722dc252e708d69c39483e871fe7941 Mon Sep 17 00:00:00 2001 From: Alexis de Lattre Date: Thu, 11 Jun 2015 12:43:43 +0200 Subject: [PATCH] Add mass allocation wizard Add counter info on form view of hr.holidays Fix an issue when checking counter --- hr_holidays_usability/__init__.py | 1 + hr_holidays_usability/__openerp__.py | 1 + hr_holidays_usability/hr_holidays.py | 61 ++++++++++++ hr_holidays_usability/hr_holidays_view.xml | 20 ++++ hr_holidays_usability/wizard/__init__.py | 2 + .../wizard/hr_holidays_mass_allocation.py | 97 +++++++++++++++++++ .../hr_holidays_mass_allocation_view.xml | 45 +++++++++ 7 files changed, 227 insertions(+) create mode 100644 hr_holidays_usability/wizard/__init__.py create mode 100644 hr_holidays_usability/wizard/hr_holidays_mass_allocation.py create mode 100644 hr_holidays_usability/wizard/hr_holidays_mass_allocation_view.xml diff --git a/hr_holidays_usability/__init__.py b/hr_holidays_usability/__init__.py index dfa6080..da27bbf 100644 --- a/hr_holidays_usability/__init__.py +++ b/hr_holidays_usability/__init__.py @@ -21,3 +21,4 @@ ############################################################################## from . import hr_holidays +from . import wizard diff --git a/hr_holidays_usability/__openerp__.py b/hr_holidays_usability/__openerp__.py index 73d60e0..3c9f9d9 100644 --- a/hr_holidays_usability/__openerp__.py +++ b/hr_holidays_usability/__openerp__.py @@ -32,6 +32,7 @@ 'website': 'http://www.akretion.com', 'depends': ['hr_holidays', 'hr_public_holidays'], 'data': [ + 'wizard/hr_holidays_mass_allocation_view.xml', 'hr_holidays_view.xml', 'hr_holidays_mail.xml', ], diff --git a/hr_holidays_usability/hr_holidays.py b/hr_holidays_usability/hr_holidays.py index 26db253..49920f5 100644 --- a/hr_holidays_usability/hr_holidays.py +++ b/hr_holidays_usability/hr_holidays.py @@ -151,6 +151,32 @@ class HrHolidays(orm.Model): res[hol.id] = days return res + def _compute_current_leaves(self, cr, uid, ids, name, arg, context=None): + res = {} + for hol in self.browse(cr, uid, ids, context=context): + if ( + hol.holiday_type == 'employee' and + hol.employee_id and + hol.holiday_status_id): + days = self.pool['hr.holidays.status'].get_days( + cr, uid, [hol.holiday_status_id.id], hol.employee_id.id, + False, context=context) + res[hol.id] = { + 'total_allocated_leaves': + days[hol.holiday_status_id.id]['max_leaves'], + 'current_leaves_taken': + days[hol.holiday_status_id.id]['leaves_taken'], + 'current_remaining_leaves': + days[hol.holiday_status_id.id]['remaining_leaves'], + } + else: + res[hol.id] = { + 'total_allocated_leaves': 0, + 'current_leaves_taken': 0, + 'current_remaining_leaves': 0, + } + return res + _columns = { 'vacation_date_from': fields.date( 'First Day of Vacation', track_visibility='onchange', @@ -181,6 +207,18 @@ class HrHolidays(orm.Model): # number_of_days is a native field that I inherit 'number_of_days': fields.function( _compute_number_of_days, string='Number of Days', store=True), + 'current_leaves_taken': fields.function( + _compute_current_leaves, string='Current Leaves Taken', + multi='usability', type='float', readonly=True), + 'current_remaining_leaves': fields.function( + _compute_current_leaves, string='Current Remaining Leaves', + multi='usability', type='float', readonly=True), + 'total_allocated_leaves': fields.function( + _compute_current_leaves, string='Total Allocated Leaves', + multi='usability', type='float', readonly=True), + 'limit': fields.related( + 'holiday_status_id', 'limit', type='boolean', + string='Allow to Override Limit') } _defaults = { @@ -288,3 +326,26 @@ class HrHolidays(orm.Model): datetime_str = datetime_dt.astimezone(pytz.utc).strftime( DEFAULT_SERVER_DATETIME_FORMAT) return {'value': {'date_to': datetime_str}} + + # Native method that I inherit + def check_holidays(self, cr, uid, ids, context=None): + holi_status_obj = self.pool.get('hr.holidays.status') + for record in self.browse(cr, uid, ids): + if record.holiday_type == 'employee' and record.type == 'remove': + if record.employee_id and not record.holiday_status_id.limit: + leaves_rest = holi_status_obj.get_days( + cr, uid, [record.holiday_status_id.id], + record.employee_id.id, + False)[record.holiday_status_id.id]['remaining_leaves'] + # here is the code that I modify + #if leaves_rest < record.number_of_days_temp: + if leaves_rest < record.number_of_days * -1: + raise orm.except_orm( + _('Warning!'), + _('There are not enough %s allocated for ' + 'employee %s (requesting %s but only %s left).') + % (record.holiday_status_id.name, + record.employee_id.name, + record.number_of_days * -1, + leaves_rest)) + return True diff --git a/hr_holidays_usability/hr_holidays_view.xml b/hr_holidays_usability/hr_holidays_view.xml index e2f97f5..a7a9718 100644 --- a/hr_holidays_usability/hr_holidays_view.xml +++ b/hr_holidays_usability/hr_holidays_view.xml @@ -34,6 +34,26 @@ + + + + + diff --git a/hr_holidays_usability/wizard/__init__.py b/hr_holidays_usability/wizard/__init__.py new file mode 100644 index 0000000..e887a00 --- /dev/null +++ b/hr_holidays_usability/wizard/__init__.py @@ -0,0 +1,2 @@ +# -*- encoding: utf-8 -*- +from . import hr_holidays_mass_allocation diff --git a/hr_holidays_usability/wizard/hr_holidays_mass_allocation.py b/hr_holidays_usability/wizard/hr_holidays_mass_allocation.py new file mode 100644 index 0000000..51da5c7 --- /dev/null +++ b/hr_holidays_usability/wizard/hr_holidays_mass_allocation.py @@ -0,0 +1,97 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# HR Holidays Usability module for Odoo +# Copyright (C) 2015 Akretion (http://www.akretion.com) +# @author Alexis de Lattre +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, either version 3 of the +# License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# +############################################################################## + +from openerp.osv import orm, fields +from openerp.tools.translate import _ +from openerp import netsvc + + +class HrHolidaysMassAllocation(orm.TransientModel): + _name = 'hr.holidays.mass.allocation' + _description = 'Wizard for mass allocation of holidays' + + def _get_all_employees(self, cr, uid, context=None): + return self.pool['hr.employee'].search(cr, uid, [], context=context) + + _columns = { + 'number_of_days': fields.float('Number of Days', required=True), + 'holiday_status_id': fields.many2one( + 'hr.holidays.status', 'Leave Type', required=True), + 'employee_ids': fields.many2many( + 'hr.employee', string='Employees'), + 'auto_approve': fields.boolean('Automatic Approval'), + # size=64 because the name field of hr.holidays is size=64 + 'name': fields.char('Description', size=64), + } + + _defaults = { + 'number_of_days': 2.08, + 'employee_ids': _get_all_employees, + 'auto_approve': True, + } + + _sql_constraints = [( + 'number_of_days_positive', + 'CHECK (number_of_days > 0)', + 'The number of days must be positive', + )] + + def run(self, cr, uid, ids, context=None): + assert len(ids) == 1, 'Only 1 ID' + wiz = self.browse(cr, uid, ids[0], context=context) + if not wiz.number_of_days: + raise orm.except_orm( + _('Error:'), + _('You must set a value for the number of days.')) + if not wiz.employee_ids: + raise orm.except_orm( + _('Error:'), + _('You must select at least one employee.')) + alloc_hol_ids = [] + hho = self.pool['hr.holidays'] + wf_service = netsvc.LocalService("workflow") + auto_approve = wiz.auto_approve + for employee in wiz.employee_ids: + hol_id = hho.create(cr, uid, { + 'name': wiz.name, + 'number_of_days_temp': wiz.number_of_days, + 'employee_id': employee.id, + 'type': 'add', + 'holiday_type': 'employee', + 'holiday_status_id': wiz.holiday_status_id.id, + }, context=context) + if auto_approve: + wf_service.trg_validate( + uid, 'hr.holidays', hol_id, 'validate', cr) + alloc_hol_ids.append(hol_id) + act_model, act_id = self.pool['ir.model.data'].get_object_reference( + cr, uid, 'hr_holidays', 'open_allocation_holidays') + assert act_model == 'ir.actions.act_window', 'Wrong model' + action = self.pool[act_model].read( + cr, uid, act_id, context=context) + action.update({ + 'target': 'current', + 'domain': [('id', 'in', alloc_hol_ids)], + 'nodestroy': True, + 'context': context, + }) + return action diff --git a/hr_holidays_usability/wizard/hr_holidays_mass_allocation_view.xml b/hr_holidays_usability/wizard/hr_holidays_mass_allocation_view.xml new file mode 100644 index 0000000..b92af37 --- /dev/null +++ b/hr_holidays_usability/wizard/hr_holidays_mass_allocation_view.xml @@ -0,0 +1,45 @@ + + + + + + + + hr_holidays_mass_allocation_form + hr.holidays.mass.allocation + +
+ + + + + + + +
+
+
+
+
+ + + Mass Allocation + hr.holidays.mass.allocation + form + new + + + + +
+