Add mass allocation wizard

Add counter info on form view of hr.holidays
Fix an issue when checking counter
This commit is contained in:
Alexis de Lattre
2015-06-11 12:43:43 +02:00
parent edcd3c7637
commit 2dbf95cb97
7 changed files with 227 additions and 0 deletions

View File

@@ -21,3 +21,4 @@
##############################################################################
from . import hr_holidays
from . import wizard

View File

@@ -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',
],

View File

@@ -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

View File

@@ -34,6 +34,26 @@
<field name="vacation_date_to" on_change="vacation_to(vacation_date_to, vacation_time_to, context)" required="1"/>
<field name="vacation_time_to" on_change="vacation_to(vacation_date_to, vacation_time_to, context)" required="1"/>
</field>
<xpath expr="//field[@name='department_id']/.." position="after">
<group string="Meter for this leave type" name="counters" attrs="{'invisible': [('limit', '=', True)]}">
<field name="limit" invisible="1"/>
<label for="total_allocated_leaves"/>
<div>
<field name="total_allocated_leaves" class="oe_inline"/>
<label string=" days" class="oe_inline"/>
</div>
<label for="current_leaves_taken"/>
<div>
<field name="current_leaves_taken" class="oe_inline"/>
<label string=" days" class="oe_inline"/>
</div>
<label for="current_remaining_leaves"/>
<div>
<field name="current_remaining_leaves" class="oe_inline"/>
<label string=" days" class="oe_inline"/>
</div>
</group>
</xpath>
</field>
</record>

View File

@@ -0,0 +1,2 @@
# -*- encoding: utf-8 -*-
from . import hr_holidays_mass_allocation

View File

@@ -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 <alexis.delattre@akretion.com>
#
# 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 <http://www.gnu.org/licenses/>.
#
##############################################################################
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

View File

@@ -0,0 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2015 Akretion (http://www.akretion.com/)
@author: Alexis de Lattre <alexis.delattre@akretion.com>
The licence is in the file __openerp__.py
-->
<openerp>
<data>
<record id="hr_holidays_mass_allocation_form" model="ir.ui.view">
<field name="name">hr_holidays_mass_allocation_form</field>
<field name="model">hr.holidays.mass.allocation</field>
<field name="arch" type="xml">
<form string="Mass Allocation of Holidays" version="7.0">
<group name="main">
<field name="name"/>
<field name="holiday_status_id"/>
<field name="employee_ids" widget="many2many_tags"/>
<field name="number_of_days"/>
<field name="auto_approve"/>
</group>
<footer>
<button name="run" type="object" string="Create Allocations"
class="oe_highlight"/>
<button special="cancel" string="Cancel" class="oe_link"/>
</footer>
</form>
</field>
</record>
<record id="hr_holidays_mass_allocation_action" model="ir.actions.act_window">
<field name="name">Mass Allocation</field>
<field name="res_model">hr.holidays.mass.allocation</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
<menuitem id="hr_holidays_mass_allocation_menu"
action="hr_holidays_mass_allocation_action"
parent="hr_holidays.menu_open_ask_holidays"
groups="base.group_hr_user"/>
</data>
</openerp>