26
26
import pytz
27
27
28
28
from openerp .osv import fields , osv
29
+ from openerp .tools import DEFAULT_SERVER_DATE_FORMAT , DEFAULT_SERVER_DATETIME_FORMAT
29
30
from openerp .tools .translate import _
30
31
from openerp import netsvc
31
- from openerp .tools import DEFAULT_SERVER_DATE_FORMAT , DEFAULT_SERVER_DATETIME_FORMAT
32
32
33
33
class hr_timesheet_sheet (osv .osv ):
34
34
_name = "hr_timesheet_sheet.sheet"
@@ -393,29 +393,53 @@ def _get_hr_timesheet_sheet(self, cr, uid, ids, context=None):
393
393
attendance_ids .extend ([row [0 ] for row in cr .fetchall ()])
394
394
return attendance_ids
395
395
396
+ def _get_attendance_employee_tz (self , cr , uid , employee_id , date , context = None ):
397
+ """ Simulate timesheet in employee timezone
398
+
399
+ Return the attendance datetime as date in string format in employee
400
+ tz converted from utc timezone as we consider date of employee
401
+ timesheet is in employee timezone
402
+ """
403
+ employee_obj = self .pool ['hr.employee' ]
404
+
405
+ tz = False
406
+ if employee_id :
407
+ employee = employee_obj .browse (cr , uid , employee_id , context = context )
408
+ tz = employee .user_id .partner_id .tz
409
+
410
+ att_tz = timezone (tz or 'utc' )
411
+
412
+ attendance_dt = datetime .strptime (date , DEFAULT_SERVER_DATETIME_FORMAT )
413
+ att_tz_dt = pytz .utc .localize (attendance_dt )
414
+ att_tz_dt = att_tz_dt .astimezone (att_tz )
415
+ # We take only the date omiting the hours as we compare with timesheet
416
+ # date_from which is a date format thus using hours would lead to
417
+ # be out of scope of timesheet
418
+ att_tz_date_str = datetime .strftime (att_tz_dt , DEFAULT_SERVER_DATE_FORMAT )
419
+ return att_tz_date_str
420
+
421
+ def _get_current_sheet (self , cr , uid , employee_id , date = False , context = None ):
422
+
423
+ sheet_obj = self .pool ['hr_timesheet_sheet.sheet' ]
424
+ if not date :
425
+ date = time .strftime (DEFAULT_SERVER_DATETIME_FORMAT )
426
+
427
+ att_tz_date_str = self ._get_attendance_employee_tz (
428
+ cr , uid , employee_id ,
429
+ date = date , context = context )
430
+ sheet_ids = sheet_obj .search (cr , uid ,
431
+ [('date_from' , '<=' , att_tz_date_str ),
432
+ ('date_to' , '>=' , att_tz_date_str ),
433
+ ('employee_id' , '=' , employee_id )],
434
+ context = context )
435
+ return sheet_ids and sheet_ids [0 ] or False
436
+
396
437
def _sheet (self , cursor , user , ids , name , args , context = None ):
397
- sheet_obj = self .pool .get ('hr_timesheet_sheet.sheet' )
398
438
res = {}.fromkeys (ids , False )
399
439
for attendance in self .browse (cursor , user , ids , context = context ):
400
-
401
- # Simulate timesheet in employee timezone
402
- att_tz = timezone (attendance .employee_id .user_id .partner_id .tz or 'utc' )
403
-
404
- attendance_dt = datetime .strptime (attendance .name , DEFAULT_SERVER_DATETIME_FORMAT )
405
- att_tz_dt = pytz .utc .localize (attendance_dt )
406
- att_tz_dt = att_tz_dt .astimezone (att_tz )
407
- # We take only the date omiting the hours as we compare with timesheet
408
- # date_from which is a date format thus using hours would lead to
409
- # be out of scope of timesheet
410
- att_tz_date_str = datetime .strftime (att_tz_dt , DEFAULT_SERVER_DATE_FORMAT )
411
- sheet_ids = sheet_obj .search (cursor , user ,
412
- [('date_from' , '<=' , att_tz_date_str ),
413
- ('date_to' , '>=' , att_tz_date_str ),
414
- ('employee_id' , '=' , attendance .employee_id .id )],
415
- context = context )
416
- if sheet_ids :
417
- # [0] because only one sheet possible for an employee between 2 dates
418
- res [attendance .id ] = sheet_obj .name_get (cursor , user , sheet_ids , context = context )[0 ]
440
+ res [attendance .id ] = self ._get_current_sheet (
441
+ cursor , user , attendance .employee_id .id , attendance .name ,
442
+ context = context )
419
443
return res
420
444
421
445
_columns = {
@@ -434,16 +458,18 @@ def _sheet(self, cursor, user, ids, name, args, context=None):
434
458
def create (self , cr , uid , vals , context = None ):
435
459
if context is None :
436
460
context = {}
437
- if 'sheet_id' in context :
438
- ts = self .pool .get ('hr_timesheet_sheet.sheet' ).browse (cr , uid , context ['sheet_id' ], context = context )
461
+
462
+ sheet_id = context .get ('sheet_id' ) or self ._get_current_sheet (cr , uid , vals .get ('employee_id' ), vals .get ('name' ), context = context )
463
+ if sheet_id :
464
+ att_tz_date_str = self ._get_attendance_employee_tz (
465
+ cr , uid , vals .get ('employee_id' ),
466
+ date = vals .get ('name' ), context = context )
467
+ ts = self .pool .get ('hr_timesheet_sheet.sheet' ).browse (cr , uid , sheet_id , context = context )
439
468
if ts .state not in ('draft' , 'new' ):
440
- raise osv .except_osv (_ ('Error!' ), _ ('You cannot modify an entry in a confirmed timesheet.' ))
441
- res = super (hr_attendance ,self ).create (cr , uid , vals , context = context )
442
- if 'sheet_id' in context :
443
- if context ['sheet_id' ] != self .browse (cr , uid , res , context = context ).sheet_id .id :
444
- raise osv .except_osv (_ ('User Error!' ), _ ('You cannot enter an attendance ' \
445
- 'date outside the current timesheet dates.' ))
446
- return res
469
+ raise osv .except_osv (_ ('Error!' ), _ ('You can not enter an attendance in a submitted timesheet. Ask your manager to reset it before adding attendance.' ))
470
+ elif ts .date_from > att_tz_date_str or ts .date_to < att_tz_date_str :
471
+ raise osv .except_osv (_ ('User Error!' ), _ ('You can not enter an attendance date outside the current timesheet dates.' ))
472
+ return super (hr_attendance ,self ).create (cr , uid , vals , context = context )
447
473
448
474
def unlink (self , cr , uid , ids , * args , ** kwargs ):
449
475
if isinstance (ids , (int , long )):
@@ -597,4 +623,3 @@ class res_company(osv.osv):
597
623
res_company ()
598
624
599
625
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
600
-
0 commit comments