[FIX] Schedule jobs even if their next time has passed.
[odoo/odoo.git] / addons / hr_holidays / hr.py
index 98a64c7..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)])
@@ -69,14 +69,15 @@ class hr_holidays_per_user(osv.osv):
 
     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):
+            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:
-                    days += holiday.number_of_days
+                    if holiday.number_of_days > 0:
+                        days += holiday.number_of_days
             days = holiday_user.max_leaves - days
             result[holiday_user.id] = days
         return result
@@ -110,7 +111,7 @@ class hr_holidays(osv.osv):
 
     _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)]}),
@@ -118,7 +119,7 @@ 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, readonly=True, states={'draft': [('readonly', False)]}),
+        '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')
     }
@@ -130,10 +131,44 @@ 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_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_holiday(self, cr, uid, ids):
         holidays_user_obj = self.pool.get('hr.holidays.per.user')
@@ -177,8 +212,11 @@ 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_holiday(cr, uid, ids)
         return True
@@ -197,6 +235,8 @@ class hr_holidays(osv.osv):
 
     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]
@@ -205,18 +245,7 @@ class hr_holidays(osv.osv):
         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'
             })
@@ -232,17 +261,18 @@ class hr_holidays(osv.osv):
 
     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
@@ -258,19 +288,35 @@ 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()
 
-# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file
+class holiday_user_log(osv.osv):
+    _name = 'hr.holidays.log'
+    _description = 'hr.holidays.log'
+    _order = "holiday_req_id desc"
+    _columns = {
+        'name' : fields.char('Action', size=64, readonly=True),
+        'holiday_req_id' : fields.char('Holiday Request ID', size=64),
+        'nb_holidays' : fields.float('Number of Holidays Requested'),
+        'employee_id' : fields.many2one('hr.employee', 'Employee', readonly=True),
+        'holiday_status' : fields.many2one("hr.holidays.status", "Holiday's Status", readonly=True),
+        'holiday_user_id' : fields.many2one('hr.holidays.per.user', 'Holidays user'),
+        'date': fields.datetime('Date'),
+                }
+    _defaults = {
+        'date': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
+    }
+holiday_user_log()