[FIX] Schedule jobs even if their next time has passed.
[odoo/odoo.git] / addons / hr_holidays / hr.py
index 8ea93ce..e57d019 100644 (file)
@@ -34,7 +34,7 @@ import pooler
 import netsvc
 import datetime
 from osv import fields, osv
-
+from tools.translate import _
 
 def _employee_get(obj,cr,uid,context={}):
     ids = obj.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)])
@@ -62,13 +62,56 @@ class hr_holidays_status(osv.osv):
     }
 hr_holidays_status()
 
+class hr_holidays_per_user(osv.osv):
+    _name = "hr.holidays.per.user"
+    _description = "Holidays Per User"
+    _rec_name = "user_id"
+
+    def _get_remaining_leaves(self, cr, uid, ids, field_name, arg=None, context={}):
+        obj_holiday = self.pool.get('hr.holidays')
+        result = {}
+        for holiday_user in self.browse(cr, uid, ids):
+            days = 0.0
+            ids_request = obj_holiday.search(cr, uid, [('employee_id', '=', holiday_user.employee_id.id),('state', '=', 'validate'),('holiday_status', '=', holiday_user.holiday_status.id)])
+            if ids_request:
+                holidays = obj_holiday.browse(cr, uid, ids_request)
+                for holiday in holidays:
+                    if holiday.number_of_days > 0:
+                        days += holiday.number_of_days
+            days = holiday_user.max_leaves - days
+            result[holiday_user.id] = days
+        return result
+
+    _columns = {
+        'employee_id': fields.many2one('hr.employee', 'Employee',required=True),
+        'user_id' : fields.many2one('res.users','User'),
+        'holiday_status' : fields.many2one("hr.holidays.status", "Holiday's Status", required=True),
+        'max_leaves' : fields.float('Maximum Leaves Allowed',required=True),
+        'leaves_taken' : fields.float('Leaves Already Taken',readonly=True),
+        'active' : fields.boolean('Active'),
+        'notes' : fields.text('Notes'),
+        'remaining_leaves': fields.function(_get_remaining_leaves, method=True, string='Remaining Leaves', type='float'),
+        'holiday_ids': fields.one2many('hr.holidays', 'holiday_user_id', 'Holidays')
+    }
+    _defaults = {
+        'active' : lambda *a: True,
+    }
+
+    def create(self, cr, uid, vals, *args, **kwargs):
+        if vals['employee_id']:
+            obj_emp=self.pool.get('hr.employee').browse(cr,uid,vals['employee_id'])
+            vals.update({'user_id': obj_emp.user_id.id})
+        return super(osv.osv,self).create(cr, uid, vals, *args, **kwargs)
+
+hr_holidays_per_user()
+
 class hr_holidays(osv.osv):
     _name = "hr.holidays"
     _description = "Holidays"
 
     _columns = {
         'name' : fields.char('Description', required=True, readonly=True, size=64, states={'draft':[('readonly',False)]}),
-        'state': fields.selection([('draft', 'draft'), ('confirm', 'Waiting Validation'), ('refuse', 'Refused'), ('validate', 'Validate'), ('cancel', 'Cancel')], 'Status', readonly=True),
+        'state': fields.selection([('draft', 'Draft'), ('confirm', 'Waiting Validation'), ('refuse', 'Refused'), ('validate', 'Validate'), ('cancel', 'Cancel')], 'Status', readonly=True),
         'date_from' : fields.datetime('Vacation start day', required=True, readonly=True, states={'draft':[('readonly',False)]}),
         'date_to' : fields.datetime('Vacation end day',required=True,readonly=True, states={'draft':[('readonly',False)]}),
         'holiday_status' : fields.many2one("hr.holidays.status", "Holiday's Status", required=True,readonly=True, states={'draft':[('readonly',False)]}),
@@ -76,8 +119,9 @@ class hr_holidays(osv.osv):
         'user_id':fields.many2one('res.users', 'Employee_id', states={'draft':[('readonly',False)]}, select=True, readonly=True),
         'manager_id' : fields.many2one('hr.employee', 'Holiday manager', invisible=False, readonly=True),
         'notes' : fields.text('Notes',readonly=True, states={'draft':[('readonly',False)]}),
-        'number_of_days': fields.float('Number of Days in this Holiday Request',required=True),
-        'case_id':fields.many2one('crm.case', 'Case'),
+        'number_of_days': fields.float('Number of Days in this Holiday Request', required=True, readonly=True, states={'draft': [('readonly', False)]}, help="An employee can make a negative holiday request (holiday request of -2 days for example), this is considered by the system as an ask for more off-days. It will increase his total of that holiday status available (if the request is accepted). For the same, make sure the days you enter are negative and both the dates are same."),
+        'case_id': fields.many2one('crm.case', 'Case'),
+        'holiday_user_id': fields.many2one('hr.holidays.per.user', 'Holiday per user')
     }
 
     _defaults = {
@@ -87,29 +131,55 @@ class hr_holidays(osv.osv):
     }
     _order = 'date_from desc'
 
+    def _update_user_holidays(self, cr, uid, ids):
+        for record in self.browse(cr, uid, ids):
+            if record.state=='validate':
+                holiday_id=self.pool.get('hr.holidays.per.user').search(cr, uid, [('employee_id','=', record.employee_id.id),('holiday_status','=',record.holiday_status.id)])
+                if holiday_id:
+                    obj_holidays_per_user=self.pool.get('hr.holidays.per.user').browse(cr, uid,holiday_id[0])
+                    self.pool.get('hr.holidays.per.user').write(cr,uid,obj_holidays_per_user.id,{'leaves_taken':obj_holidays_per_user.leaves_taken - record.number_of_days})
+                if record.case_id:
+                    if record.case_id.state <> 'draft':
+                        raise osv.except_osv(_('Warning !'),
+                    _('You can not cancel this holiday request. first You have to make its case in draft state.'))
+                    else:
+                        self.pool.get('crm.case').unlink(cr,uid,[record.case_id.id])
+                        
+    def _check_date(self, cr, uid, ids):
+        for rec in self.read(cr, uid, ids, ['number_of_days','date_from','date_to']):
+            if rec['number_of_days'] == 0.0:
+                return False
+            date_from = time.strptime(rec['date_from'], '%Y-%m-%d %H:%M:%S')
+            date_to = time.strptime(rec['date_to'], '%Y-%m-%d %H:%M:%S')
+            if rec['number_of_days'] < 0:
+                if date_from <> date_to:
+                    return False
+            else:
+                if date_from > date_to:
+                    return False
+        return True
+
+    _constraints = [(_check_date, 'The Holiday request seems invalid due to one of the following reasons:\n1. Start date is greater than End date!\n2. Number of Day(s) asked for leave(s) are zero!\n3. You are requesting more holidays by putting negative days,but both the dates are not same! ', ['number_of_days'])]
+
     def create(self, cr, uid, vals, *args, **kwargs):
         id_holiday = super(hr_holidays, self).create(cr, uid, vals, *args, **kwargs)
-        self._create_log(cr, uid, [id_holiday])
+        self._create_holiday(cr, uid, [id_holiday])
         return id_holiday
+    
+    def unlink(self, cr, uid, ids, context={}):
+        self._update_user_holidays(cr, uid, ids)
+        return super(hr_holidays, self).unlink(cr, uid, ids, context)
 
-    def _create_log(self, cr, uid, ids):
+    def _create_holiday(self, cr, uid, ids):
         holidays_user_obj = self.pool.get('hr.holidays.per.user')
-        list_request = []
         holidays_data = self.browse(cr, uid, ids[0])
-        datas = {
-         'employee_id' : holidays_data.employee_id.id,
-         'name' : holidays_data.state,
-         'holiday_status' : holidays_data.holiday_status.id,
-         'holiday_req_id' : holidays_data.id,
-         'nb_holidays' : holidays_data.number_of_days
-         }
-        ids_log = self.pool.get('hr.holidays.log').create(cr, uid, datas)
+        list_holiday = []
         ids_user_hdays = holidays_user_obj.search(cr, uid, [('employee_id', '=', holidays_data.employee_id.id),('holiday_status', '=', holidays_data.holiday_status.id)])
         for hdays in holidays_user_obj.browse(cr, uid, ids_user_hdays):
-            for req in hdays.history:
-                list_request.append(req.id)
-        list_request.append(ids_log)
-        holidays_user_obj.write(cr, uid, ids_user_hdays, {'history' : [(6,0,list_request)]})
+            for req in hdays.holiday_ids:
+                list_holiday.append(req.id)
+        list_holiday.append(ids[0])
+        holidays_user_obj.write(cr, uid, ids_user_hdays, {'holiday_ids': [(6, 0, list_holiday)]})
         return True
 
     def onchange_date_to(self, cr, uid, ids, date_from, date_to):
@@ -133,7 +203,7 @@ class hr_holidays(osv.osv):
             'state':'draft',
             'manager_id': False
         })
-        self._create_log(cr, uid, ids)
+        self._create_holiday(cr, uid, ids)
         return True
 
     def holidays_validate(self, cr, uid, ids, *args):
@@ -142,10 +212,13 @@ class hr_holidays(osv.osv):
             'state':'validate',
         }
         ids2 = self.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)])
+        
         if ids2:
             vals['manager_id'] = ids2[0]
+        else:
+            raise osv.except_osv(_('Warning !'),_('Either there is no Employee defined, or no User attached with it.'))    
         self.write(cr, uid, ids, vals)
-        self._create_log(cr, uid, ids)
+        self._create_holiday(cr, uid, ids)
         return True
 
     def holidays_confirm(self, cr, uid, ids, *args):
@@ -157,57 +230,49 @@ class hr_holidays(osv.osv):
             'state':'confirm',
             'user_id': user,
         })
-        self._create_log(cr, uid, ids)
+        self._create_holiday(cr, uid, ids)
         return True
 
     def holidays_refuse(self, cr, uid, ids, *args):
         ids2 = self.pool.get('hr.employee').search(cr, uid, [('user_id','=', uid)])
+        if not ids2:
+            raise osv.except_osv(_('Warning !'),_('Either there is no Employee defined, or no User attached with it.'))
         self.write(cr, uid, ids, {
             'state':'refuse',
             'manager_id':ids2[0]
         })
-        self._create_log(cr, uid, ids)
+        self._create_holiday(cr, uid, ids)
         return True
 
     def holidays_cancel(self, cr, uid, ids, *args):
-        for record in self.browse(cr, uid, ids):
-            if record.state=='validate':
-                holiday_id=self.pool.get('hr.holidays.per.user').search(cr, uid, [('employee_id','=', record.employee_id.id),('holiday_status','=',record.holiday_status.id)])
-                if holiday_id:
-                    obj_holidays_per_user=self.pool.get('hr.holidays.per.user').browse(cr, uid,holiday_id[0])
-                    self.pool.get('hr.holidays.per.user').write(cr,uid,obj_holidays_per_user.id,{'leaves_taken':obj_holidays_per_user.leaves_taken - record.number_of_days})
-                if record.case_id:
-                    if record.case_id.state <> 'draft':
-                        raise osv.except_osv(_('Warning !'),
-                    _('You can not cancel this holiday request. first You have to make its case in draft state.'))
-                    else:
-                        self.pool.get('crm.case').unlink(cr,uid,[record.case_id.id])
+        self._update_user_holidays(cr, uid, ids)
         self.write(cr, uid, ids, {
             'state':'cancel'
             })
-        self._create_log(cr, uid, ids)
+        self._create_holiday(cr, uid, ids)
         return True
 
     def holidays_draft(self, cr, uid, ids, *args):
         self.write(cr, uid, ids, {
             'state':'draft'
         })
-        self._create_log(cr, uid, ids)
+        self._create_holiday(cr, uid, ids)
         return True
 
     def check_holidays(self,cr,uid,ids):
 
+        holiday_user_pool = self.pool.get('hr.holidays.per.user')
         for record in self.browse(cr, uid, ids):
             leave_asked = record.number_of_days
-            holiday_id=self.pool.get('hr.holidays.per.user').search(cr, uid, [('employee_id','=', record.employee_id.id),('holiday_status','=',record.holiday_status.id)])
+            holiday_id = holiday_user_pool.search(cr, uid, [('employee_id','=', record.employee_id.id),('holiday_status','=',record.holiday_status.id)])
             if leave_asked>=0.00:
                 if holiday_id:
-                    obj_holidays_per_user=self.pool.get('hr.holidays.per.user').browse(cr, uid,holiday_id[0])
-                    leaves_rest=obj_holidays_per_user.max_leaves - obj_holidays_per_user.leaves_taken
+                    obj_holidays_per_user = holiday_user_pool.browse(cr, uid,holiday_id[0])
+                    leaves_rest = obj_holidays_per_user.max_leaves - obj_holidays_per_user.leaves_taken
                     if not obj_holidays_per_user.holiday_status.limit:
                         if leaves_rest < leave_asked:
-                            raise osv.except_osv('Attention!','You Cannot Validate leaves while available leaves are less than asked leaves.')
-                    self.pool.get('hr.holidays.per.user').write(cr,uid,obj_holidays_per_user.id,{'leaves_taken':obj_holidays_per_user.leaves_taken + leave_asked})
+                            raise osv.except_osv(_('Attention!'),_('You Cannot Validate leaves while available leaves are less than asked leaves.'))
+                    holiday_user_pool.write(cr,uid,obj_holidays_per_user.id,{'leaves_taken':obj_holidays_per_user.leaves_taken + leave_asked})
                 if record.holiday_status.section_id:
                     vals={}
                     vals['name']=record.name
@@ -223,64 +288,21 @@ class hr_holidays(osv.osv):
                     self.write(cr, uid, ids, {'case_id':case_id})
             else:
                 if holiday_id:
-                    obj_holidays_per_user=self.pool.get('hr.holidays.per.user').browse(cr, uid,holiday_id[0])
-                    note=obj_holidays_per_user.notes or ''
-                    notes= note + '\n***' + time.strftime('%Y-%m-%d %H:%M:%S') + ' ' + record.name
-                    self.pool.get('hr.holidays.per.user').write(cr,uid,obj_holidays_per_user.id,{'max_leaves':obj_holidays_per_user.max_leaves + abs(leave_asked),'notes':notes})
+                    obj_holidays_per_user = holiday_user_pool.browse(cr, uid,holiday_id[0])
+                    note = obj_holidays_per_user.notes or ''
+                    notes = note + '\n*** Reference Id [' + str(record.id) + '] : ' + str(abs(leave_asked)) + ' leaves added on ' + time.strftime('%Y-%m-%d %H:%M:%S') + ' Description: ' + record.name
+                    holiday_user_pool.write(cr,uid,obj_holidays_per_user.id,{'max_leaves':obj_holidays_per_user.max_leaves + abs(leave_asked),'notes':notes})
                 else:
-                    vals={}
-                    vals['employee_id']=record.employee_id.id
-                    vals['holiday_status']=record.holiday_status.id
-                    vals['max_leaves']=abs(leave_asked)
-                    vals['leaves_taken']=0.00
-                    self.pool.get('hr.holidays.per.user').create(cr,uid,vals)
+                    vals = {}
+                    vals['employee_id'] = record.employee_id.id
+                    vals['holiday_status'] = record.holiday_status.id
+                    vals['max_leaves'] = abs(leave_asked)
+                    vals['leaves_taken'] = 0.00
+                    holiday_user_pool.create(cr,uid,vals)
 
         return True
 hr_holidays()
 
-
-class hr_holidays_per_user(osv.osv):
-    _name = "hr.holidays.per.user"
-    _description = "Holidays Per User"
-    _rec_name = 'user_id'
-
-    def _get_remaining_leaves(self, cr, uid, ids, field_name, arg=None, context={}):
-        obj_holiday = self.pool.get('hr.holidays')
-        days = 0.0
-        result = {}
-        for holiday_user in self.browse(cr, uid, ids):
-            ids_request = obj_holiday.search(cr, uid, [('employee_id', '=', holiday_user.employee_id.id),('state', '=', 'validate'),('holiday_status', '=', holiday_user.holiday_status.id)])
-            if ids_request:
-                holidays = obj_holiday.browse(cr, uid, ids_request)
-                for holiday in holidays:
-                    days += holiday.number_of_days
-            days = holiday_user.max_leaves - days
-            result[holiday_user.id] = days
-        return result
-
-    _columns = {
-        'employee_id' : fields.many2one('hr.employee', 'Employee',required=True),
-        'user_id' : fields.many2one('res.users','User'),
-        'holiday_status' : fields.many2one("hr.holidays.status", "Holiday's Status", required=True),
-        'max_leaves' : fields.float('Maximum Leaves Allowed',required=True),
-        'leaves_taken' : fields.float('Leaves Already Taken',readonly=True),
-        'active' : fields.boolean('Active'),
-        'notes' : fields.text('Notes'),
-        'remaining_leaves': fields.function(_get_remaining_leaves, method=True, string='Remaining Leaves', type='float'),
-        'history' : fields.one2many('hr.holidays.log', 'holiday_user_id', 'History')
-    }
-    _defaults = {
-        'active' : lambda *a: True,
-    }
-
-    def create(self, cr, uid, vals, *args, **kwargs):
-        if vals['employee_id']:
-            obj_emp=self.pool.get('hr.employee').browse(cr,uid,vals['employee_id'])
-            vals.update({'user_id': obj_emp.user_id.id})
-        return super(osv.osv,self).create(cr, uid, vals, *args, **kwargs)
-
-hr_holidays_per_user()
-
 class holiday_user_log(osv.osv):
     _name = 'hr.holidays.log'
     _description = 'hr.holidays.log'
@@ -298,6 +320,3 @@ class holiday_user_log(osv.osv):
         'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
     }
 holiday_user_log()
-
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
-