diff --git a/addons/hr_holidays/hr_holidays.py b/addons/hr_holidays/hr_holidays.py index 5840217d7ee..f687e91c3f0 100644 --- a/addons/hr_holidays/hr_holidays.py +++ b/addons/hr_holidays/hr_holidays.py @@ -25,6 +25,7 @@ import datetime, time from itertools import groupby from operator import itemgetter +import math import netsvc from osv import fields, osv from tools.translate import _ @@ -112,7 +113,7 @@ class hr_holidays(osv.osv): return result _columns = { - 'name': fields.char('Description', required=True, size=64), + 'name': fields.char('Description', size=64), 'state': fields.selection([('draft', 'To Submit'), ('cancel', 'Cancelled'),('confirm', 'To Approve'), ('refuse', 'Refused'), ('validate1', 'Second Approval'), ('validate', 'Approved')], 'State', readonly=True, help='The state is set to \'To Submit\', when a holiday request is created.\ \nThe state is \'To Approve\', when holiday request is confirmed by user.\ @@ -123,8 +124,6 @@ class hr_holidays(osv.osv): 'date_to': fields.datetime('End Date', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'holiday_status_id': fields.many2one("hr.holidays.status", "Leave Type", required=True,readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'employee_id': fields.many2one('hr.employee', "Employee", select=True, invisible=False, readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}, help='Leave Manager can let this field empty if this leave request/allocation is for every employee'), - #'manager_id': fields.many2one('hr.employee', 'Leave Manager', invisible=False, readonly=True, help='This area is automatically filled by the user who validate the leave'), - #'notes': fields.text('Notes',readonly=True, states={'draft':[('readonly',False)]}), 'manager_id': fields.many2one('hr.employee', 'First Approval', invisible=False, readonly=True, help='This area is automatically filled by the user who validate the leave'), 'notes': fields.text('Reasons',readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), 'number_of_days_temp': fields.float('Number of Days', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), @@ -134,8 +133,8 @@ class hr_holidays(osv.osv): 'parent_id': fields.many2one('hr.holidays', 'Parent'), 'linked_request_ids': fields.one2many('hr.holidays', 'parent_id', 'Linked Requests',), 'department_id':fields.related('employee_id', 'department_id', string='Department', type='many2one', relation='hr.department', readonly=True, store=True), - 'category_id': fields.many2one('hr.employee.category', "Category", help='Category of Employee'), - 'holiday_type': fields.selection([('employee','By Employee'),('category','By Employee Category')], 'Allocation Type', help='By Employee: Allocation/Request for individual Employee, By Employee Category: Allocation/Request for group of employees in category', required=True), + 'category_id': fields.many2one('hr.employee.category', "Category", help='Category of Employee', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}), + 'holiday_type': fields.selection([('employee','By Employee'),('category','By Employee Category')], 'Allocation Mode', readonly=True, states={'draft':[('readonly',False)], 'confirm':[('readonly',False)]}, help='By Employee: Allocation/Request for individual Employee, By Employee Category: Allocation/Request for group of employees in category', required=True), 'manager_id2': fields.many2one('hr.employee', 'Second Approval', readonly=True, help='This area is automaticly filled by the user who validate the leave with second level (If Leave type need second validation)'), 'double_validation': fields.related('holiday_status_id', 'double_validation', type='boolean', relation='hr.holidays.status', string='Apply Double Validation'), } @@ -147,16 +146,11 @@ class hr_holidays(osv.osv): 'holiday_type': 'employee' } _sql_constraints = [ - ('type_value', "CHECK( (holiday_type='employee' AND employee_id IS NOT NULL) or (holiday_type='category' AND category_id IS NOT NULL))", "You have to select an employee or a category."), + ('type_value', "CHECK( (holiday_type='employee' AND employee_id IS NOT NULL) or (holiday_type='category' AND category_id IS NOT NULL))", "The employee or employee category of this request is missing."), ('date_check2', "CHECK ( (type='add') OR (date_from <= date_to))", "The start date must be before the end date !"), ('date_check', "CHECK ( number_of_days_temp >= 0 )", "The number of days must be greater than 0 !"), ] - def create(self, cr, uid, vals, context=None): - obj_id = super(hr_holidays, self).create(cr, uid, vals, context=context) - self.create_notificate(cr, uid, [obj_id], context=context) - return obj_id - def _create_resource_leave(self, cr, uid, leaves, context=None): '''This method will create entry in resource calendar leave object at the time of holidays validated ''' obj_res_leave = self.pool.get('resource.calendar.leaves') @@ -201,8 +195,8 @@ class hr_holidays(osv.osv): def unlink(self, cr, uid, ids, context=None): for rec in self.browse(cr, uid, ids, context=context): - if rec.state<>'draft': - raise osv.except_osv(_('Warning!'),_('You cannot delete a leave which is not in draft state !')) + if rec.state not in ['draft', 'cancel', 'confirm']: + raise osv.except_osv(_('Warning!'),_('You cannot delete a leave which is in %s state!')%(rec.state)) return super(hr_holidays, self).unlink(cr, uid, ids, context) def onchange_date_from(self, cr, uid, ids, date_to, date_from): @@ -210,7 +204,7 @@ class hr_holidays(osv.osv): if date_to and date_from: diff_day = self._get_number_of_days(date_from, date_to) result['value'] = { - 'number_of_days_temp': round(diff_day)+1 + 'number_of_days_temp': round(math.floor(diff_day))+1 } return result result['value'] = { @@ -244,29 +238,30 @@ class hr_holidays(osv.osv): self.unlink(cr, uid, to_unlink, context=context) return True - def holidays_validate(self, cr, uid, ids, context=None): + def holidays_first_validate(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) obj_emp = self.pool.get('hr.employee') ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)]) manager = ids2 and ids2[0] or False - self.holidays_validate_notificate(cr, uid, ids, context=context) + self.holidays_first_validate_notificate(cr, uid, ids, context=context) return self.write(cr, uid, ids, {'state':'validate1', 'manager_id': manager}) - def holidays_validate2(self, cr, uid, ids, context=None): + def holidays_validate(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) obj_emp = self.pool.get('hr.employee') ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)]) manager = ids2 and ids2[0] or False self.write(cr, uid, ids, {'state':'validate'}) data_holiday = self.browse(cr, uid, ids) - holiday_ids = [] for record in data_holiday: - if record.holiday_status_id.double_validation: - holiday_ids.append(record.id) + if record.double_validation: + self.write(cr, uid, [record.id], {'manager_id2': manager}) + else: + self.write(cr, uid, [record.id], {'manager_id': manager}) if record.holiday_type == 'employee' and record.type == 'remove': meeting_obj = self.pool.get('crm.meeting') meeting_vals = { - 'name': record.name, + 'name': record.name or _('Leave Request'), 'categ_ids': record.holiday_status_id.categ_id and [(6,0,[record.holiday_status_id.categ_id.id])] or [], 'duration': record.number_of_days_temp * 8, 'description': record.notes, @@ -301,25 +296,27 @@ class hr_holidays(osv.osv): wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'confirm', cr) wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'validate', cr) wf_service.trg_validate(uid, 'hr.holidays', leave_id, 'second_validate', cr) - if holiday_ids: - self.holidays_valid2_notificate(cr, uid, holiday_ids, context=context) - self.write(cr, uid, holiday_ids, {'manager_id2': manager}) + self.holidays_validate_notificate(cr, uid, ids, context=context) return True def holidays_confirm(self, cr, uid, ids, context=None): self.check_holidays(cr, uid, ids, context=context) + for record in self.browse(cr, uid, ids, context=context): + if record.employee_id and record.employee_id.parent_id and record.employee_id.parent_id.user_id: + self.message_subscribe(cr, uid, [record.id], user_ids=[record.employee_id.parent_id.user_id.id], context=context) self.holidays_confirm_notificate(cr, uid, ids, context=context) return self.write(cr, uid, ids, {'state':'confirm'}) - def holidays_refuse(self, cr, uid, ids, approval, context=None): + def holidays_refuse(self, cr, uid, ids, context=None): obj_emp = self.pool.get('hr.employee') ids2 = obj_emp.search(cr, uid, [('user_id', '=', uid)]) manager = ids2 and ids2[0] or False - if approval == 'first_approval': - self.write(cr, uid, ids, {'state': 'refuse', 'manager_id': manager}) - else: - self.write(cr, uid, ids, {'state': 'refuse', 'manager_id2': manager}) - self.holidays_refuse_notificate(cr, uid, ids, approval, context=context) + for holiday in self.browse(cr, uid, ids, context=context): + if holiday.state == 'validate1': + self.write(cr, uid, [holiday.id], {'state': 'refuse', 'manager_id': manager}) + else: + self.write(cr, uid, [holiday.id], {'state': 'refuse', 'manager_id2': manager}) + self.holidays_refuse_notificate(cr, uid, ids, context=context) self.holidays_cancel(cr, uid, ids, context=context) return True @@ -333,7 +330,7 @@ class hr_holidays(osv.osv): # If a category that created several holidays, cancel all related wf_service = netsvc.LocalService("workflow") for request in record.linked_request_ids or []: - wf_service.trg_validate(uid, 'hr.holidays', request.id, 'cancel', cr) + wf_service.trg_validate(uid, 'hr.holidays', request.id, 'refuse', cr) self._remove_resource_leave(cr, uid, ids, context=context) return True @@ -355,7 +352,7 @@ class hr_holidays(osv.osv): def get_needaction_user_ids(self, cr, uid, ids, context=None): result = super(hr_holidays, self).get_needaction_user_ids(cr, uid, ids, context=context) for obj in self.browse(cr, uid, ids, context=context): - if obj.state == 'confirm' and obj.employee_id.parent_id: + if obj.state == 'confirm' and obj.holiday_type == 'employee' and obj.employee_id.parent_id: result[obj.id] = [obj.employee_id.parent_id.user_id.id] elif obj.state == 'validate1': # get group_hr_manager: everyone will be warned of second validation @@ -369,44 +366,38 @@ class hr_holidays(osv.osv): def message_get_monitored_follower_fields(self, cr, uid, ids, context=None): """ Add 'user_id' and 'manager' to the monitored fields """ res = super(hr_holidays, self).message_get_monitored_follower_fields(cr, uid, ids, context=context) - # TODO: add manager return res + ['user_id'] def create_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids, context=context): self.message_append_note(cr, uid, ids, _('System notification'), - _("The %s request has been created and is waiting confirmation.") - % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context) + _("The request has been created and is waiting confirmation."), type='notification', context=context) return True def holidays_confirm_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_append_note(cr, uid, [obj.id], _('System notification'), - _("The %s request has been confirmed and is waiting for validation by the manager.") - % ('leave' if obj.type == 'remove' else 'allocation',), type='notification') + _("The request has been submitted and is waiting for validation by the manager."), type='notification') + def holidays_first_validate_notificate(self, cr, uid, ids, context=None): + for obj in self.browse(cr, uid, ids, context=context): + self.message_append_note(cr, uid, [obj.id], _('System notification'), + _("The request has been approved. A second validation is necessary and is now pending."), type='notification', context=context) + def holidays_validate_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): - if obj.holiday_status_id.double_validation: + if obj.double_validation: self.message_append_note(cr, uid, [obj.id], _('System notification'), - _("The %s request has been approved. A second validation is necessary and is now pending.") - % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context) + _("The request has been double validated. The validation process is now over."), type='notification', context=context) else: self.message_append_note(cr, uid, [obj.id], _('System notification'), - _("The %s request has been approved. The validation process is now over.") - % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context) + _("The request has been approved. The validation process is now over."), type='notification', context=context) - def holidays_valid2_notificate(self, cr, uid, ids, context=None): + + def holidays_refuse_notificate(self, cr, uid, ids, context=None): for obj in self.browse(cr, uid, ids): self.message_append_note(cr, uid, [obj.id], _('System notification'), - _("The %s request has been double validated. The validation process is now over.") - % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context) - - def holidays_refuse_notificate(self, cr, uid, ids, approval, context=None): - for obj in self.browse(cr, uid, ids): - self.message_append_note(cr, uid, [obj.id], _('System notification'), - _("The %s request has been refused. The validation process is now over.") - % ('leave' if obj.type == 'remove' else 'allocation',), type='notification', context=context) + _("The request has been refused. The validation process is now over."), type='notification', context=context) hr_holidays() diff --git a/addons/hr_holidays/hr_holidays_demo.xml b/addons/hr_holidays/hr_holidays_demo.xml index 6ad5a442a38..4c9d18683c7 100644 --- a/addons/hr_holidays/hr_holidays_demo.xml +++ b/addons/hr_holidays/hr_holidays_demo.xml @@ -12,7 +12,7 @@ Trip with Family - + remove @@ -52,13 +52,10 @@ - - - diff --git a/addons/hr_holidays/hr_holidays_view.xml b/addons/hr_holidays/hr_holidays_view.xml index 711d07bbfe8..650445b2ade 100644 --- a/addons/hr_holidays/hr_holidays_view.xml +++ b/addons/hr_holidays/hr_holidays_view.xml @@ -84,56 +84,42 @@ - + Leave Request hr.holidays 1
-
- - - - - - + + + + - - - - - - - - - - - - - - -
@@ -150,37 +136,27 @@
-
- - - - - - - + + + + + + + - - - - - - - - - - +
@@ -225,7 +201,6 @@ - @@ -233,7 +208,7 @@ - + @@ -288,12 +263,12 @@ - Leave Requests + My Leave Requests hr.holidays form {} - [('type','=','remove')] + [('type','=','remove'),('employee_id.user_id','=', uid)]

@@ -327,7 +302,7 @@ - + @@ -357,11 +332,11 @@ - Allocation Requests + My Allocation Requests hr.holidays form {'default_type':'add'} - [('type','=','add')] + [('type','=','add'),('employee_id.user_id','=', uid)] @@ -380,7 +355,7 @@ - + Leaves Summary diff --git a/addons/hr_holidays/hr_holidays_workflow.xml b/addons/hr_holidays/hr_holidays_workflow.xml index 7013d62a5ed..a2e1d54f96c 100644 --- a/addons/hr_holidays/hr_holidays_workflow.xml +++ b/addons/hr_holidays/hr_holidays_workflow.xml @@ -2,7 +2,16 @@ - + hr.wkf.holidays @@ -10,13 +19,13 @@ True - + True draft - + confirm function @@ -24,74 +33,94 @@ OR - + validate function holidays_validate() - + - second_validate + first_validate function - holidays_validate2() + holidays_first_validate() + OR - + refuse True - stopall + function + holidays_refuse() - + - confirm - + validate + not double_validation + + + + + + + double_validation + + + + + + + + refuse True - - - - refuse - holidays_refuse('first_approval') - - - - + refuse - holidays_refuse('second_approval') + True - + - + + refuse + True + + + + + + + + True second_validate - + - - - - not holiday_status_id.double_validation - + + + + refuse + True + diff --git a/addons/hr_holidays/security/ir.model.access.csv b/addons/hr_holidays/security/ir.model.access.csv index b21b6ca64e4..0375a17ac53 100644 --- a/addons/hr_holidays/security/ir.model.access.csv +++ b/addons/hr_holidays/security/ir.model.access.csv @@ -4,5 +4,5 @@ access_hr_holidays_user,hr.holidays.user,model_hr_holidays,base.group_hr_user,1, access_hr_holidays_employee,hr.holidays.employee,model_hr_holidays,base.group_user,1,1,1,1 access_hr_holydays_status_employee,hr.holidays.status employee,model_hr_holidays_status,base.group_user,1,0,0,0 access_hr_holidays_remain_user,hr.holidays.ramain.user,model_hr_holidays_remaining_leaves_user,base.group_hr_user,1,1,1,1 -access_resource_calendar_leaves_manager,resource_calendar_leaves_manager,resource.model_resource_calendar_leaves,base.group_hr_manager,1,1,1,1 +access_resource_calendar_leaves_user,resource_calendar_leaves_user,resource.model_resource_calendar_leaves,base.group_hr_user,1,1,1,1 access_crm_meeting_type_manager,crm.meeting.type.manager,base_calendar.model_crm_meeting_type,base.group_hr_manager,1,1,1,1 diff --git a/addons/hr_holidays/security/ir_rule.xml b/addons/hr_holidays/security/ir_rule.xml index 8e8c97bf7ea..ff0270026a4 100644 --- a/addons/hr_holidays/security/ir_rule.xml +++ b/addons/hr_holidays/security/ir_rule.xml @@ -1,6 +1,19 @@ - + + Employee Holidays + + [('employee_id.user_id','=',user.id)] + + + + + Holidays Officer + + [(1,'=',1)] + + +