2007-03-05 18:22:32 +00:00
##############################################################################
#
# Copyright (c) 2006 TINY SPRL. (http://tiny.be) All Rights Reserved.
#
# $Id: hr_timesheet.py 5490 2007-01-29 16:05:51Z pinky $
#
# WARNING: This program as such is intended to be used by professional
# programmers who take the whole responsability of assessing all potential
# consequences resulting from its eventual inadequacies and bugs
# End users who are looking for a ready-to-use solution with commercial
# garantees and support are strongly adviced to contract a Free Software
# Service Company
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# 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 General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
##############################################################################
import time
from osv import fields
from osv import osv
2007-03-07 06:26:01 +00:00
import netsvc
2007-03-05 18:22:32 +00:00
from mx import DateTime
2007-03-06 06:23:48 +00:00
class one2many_mod2 ( fields . one2many ) :
def get ( self , cr , obj , ids , name , user = None , offset = 0 , context = { } , values = { } ) :
res = { }
for id in ids :
res [ id ] = [ ]
res5 = obj . read ( cr , user , ids , [ ' date_current ' ] , context )
res6 = { }
for r in res5 :
res6 [ r [ ' id ' ] ] = r [ ' date_current ' ]
for id in ids :
dom = [ ]
if id in res6 :
dom = [ ( ' name ' , ' >= ' , res6 [ id ] + ' 00:00:00 ' ) , ( ' name ' , ' <= ' , res6 [ id ] + ' 23:59:59 ' ) ]
ids2 = obj . pool . get ( self . _obj ) . search ( cr , user , [ ( self . _fields_id , ' = ' , id ) ] + dom , limit = self . _limit )
for r in obj . pool . get ( self . _obj ) . _read_flat ( cr , user , ids2 , [ self . _fields_id ] , context = context , load = ' _classic_write ' ) :
res [ r [ self . _fields_id ] ] . append ( r [ ' id ' ] )
return res
class one2many_mod ( fields . one2many ) :
def get ( self , cr , obj , ids , name , user = None , offset = 0 , context = { } , values = { } ) :
res = { }
for id in ids :
res [ id ] = [ ]
res5 = obj . read ( cr , user , ids , [ ' date_current ' ] , context )
res6 = { }
for r in res5 :
res6 [ r [ ' id ' ] ] = r [ ' date_current ' ]
for id in ids :
dom = [ ]
if id in res6 :
dom = [ ( ' date ' , ' = ' , res6 [ id ] ) ]
ids2 = obj . pool . get ( self . _obj ) . search ( cr , user , [ ( self . _fields_id , ' = ' , id ) ] + dom , limit = self . _limit )
for r in obj . pool . get ( self . _obj ) . _read_flat ( cr , user , ids2 , [ self . _fields_id ] , context = context , load = ' _classic_write ' ) :
res [ r [ self . _fields_id ] ] . append ( r [ ' id ' ] )
return res
2007-03-05 18:22:32 +00:00
class hr_timesheet_sheet ( osv . osv ) :
2007-03-06 06:23:48 +00:00
_name = " hr_timesheet_sheet.sheet "
_table = ' hr_timesheet_sheet_sheet '
_order = " id desc "
def _total_attendance_day ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
result [ day . id ] = 0.0
obj = self . pool . get ( ' hr_timesheet_sheet.sheet.day ' )
ids = obj . search ( cr , uid , [ ( ' sheet_id ' , ' = ' , day . id ) , ( ' name ' , ' = ' , day . date_current ) ] )
if ids :
result [ day . id ] = obj . read ( cr , uid , ids , [ ' total_attendance ' ] ) [ 0 ] [ ' total_attendance ' ] or 0.0
return result
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
def _total_timesheet_day ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
result [ day . id ] = 0.0
obj = self . pool . get ( ' hr_timesheet_sheet.sheet.day ' )
ids = obj . search ( cr , uid , [ ( ' sheet_id ' , ' = ' , day . id ) , ( ' name ' , ' = ' , day . date_current ) ] )
if ids :
result [ day . id ] = obj . read ( cr , uid , ids , [ ' total_timesheet ' ] ) [ 0 ] [ ' total_timesheet ' ] or 0.0
return result
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
def _total_difference_day ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
result [ day . id ] = 0.0
obj = self . pool . get ( ' hr_timesheet_sheet.sheet.day ' )
ids = obj . search ( cr , uid , [ ( ' sheet_id ' , ' = ' , day . id ) , ( ' name ' , ' = ' , day . date_current ) ] )
if ids :
result [ day . id ] = obj . read ( cr , uid , ids , [ ' total_difference ' ] ) [ 0 ] [ ' total_difference ' ] or 0.0
return result
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
def _total_attendance ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
result [ day . id ] = 0.0
obj = self . pool . get ( ' hr_timesheet_sheet.sheet.day ' )
ids = obj . search ( cr , uid , [ ( ' sheet_id ' , ' = ' , day . id ) ] )
for o in obj . browse ( cr , uid , ids , context ) :
result [ day . id ] + = o . total_attendance
return result
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
def _total_timesheet ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
result [ day . id ] = 0.0
obj = self . pool . get ( ' hr_timesheet_sheet.sheet.day ' )
ids = obj . search ( cr , uid , [ ( ' sheet_id ' , ' = ' , day . id ) ] )
for o in obj . browse ( cr , uid , ids , context ) :
result [ day . id ] + = o . total_timesheet
return result
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
def _total_difference ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
result [ day . id ] = 0.0
obj = self . pool . get ( ' hr_timesheet_sheet.sheet.day ' )
ids = obj . search ( cr , uid , [ ( ' sheet_id ' , ' = ' , day . id ) ] )
for o in obj . browse ( cr , uid , ids , context ) :
result [ day . id ] + = o . total_difference
return result
2007-03-05 18:22:32 +00:00
2007-03-06 09:55:17 +00:00
def _state_attendance ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
emp_obj = self . pool . get ( ' hr.employee ' )
emp_ids = emp_obj . search ( cr , uid , [ ( ' user_id ' , ' = ' , day . user_id . id ) ] )
if emp_ids :
result [ day . id ] = emp_obj . browse ( cr , uid , emp_ids [ 0 ] , context ) . state
else :
result [ day . id ] = ' none '
return result
2007-03-07 06:26:01 +00:00
def button_confirm ( self , cr , uid , ids , context ) :
2007-03-06 09:55:17 +00:00
for sheet in self . browse ( cr , uid , ids , context ) :
2007-03-07 06:26:01 +00:00
di = sheet . user_id . company_id . timesheet_max_difference
if ( abs ( sheet . total_difference ) < di ) or not di :
wf_service = netsvc . LocalService ( " workflow " )
wf_service . trg_validate ( uid , ' hr_timesheet_sheet.sheet ' , sheet . id , ' confirm ' , cr )
else :
raise osv . except_osv ( ' Warning ! ' , ' Please verify that the total difference of the sheet is lower than %.2f ! ' % ( di , ) )
return True
def date_today ( self , cr , uid , ids , context ) :
2007-03-26 13:52:53 +00:00
for sheet in self . browse ( cr , uid , ids , context ) :
if DateTime . now ( ) < = DateTime . strptime ( sheet . date_from , ' % Y- % m- %d ' ) :
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_from , } )
elif DateTime . now ( ) > = DateTime . strptime ( sheet . date_to , ' % Y- % m- %d ' ) :
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_to , } )
else :
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : time . strftime ( ' % Y- % m- %d ' ) } )
2007-03-06 09:55:17 +00:00
return True
2007-03-06 06:23:48 +00:00
def date_previous ( self , cr , uid , ids , context ) :
for sheet in self . browse ( cr , uid , ids , context ) :
2007-03-26 13:52:53 +00:00
if DateTime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) < = DateTime . strptime ( sheet . date_from , ' % Y- % m- %d ' ) :
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_from , } )
else :
self . write ( cr , uid , [ sheet . id ] , {
' date_current ' : ( DateTime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) + DateTime . RelativeDateTime ( days = - 1 ) ) . strftime ( ' % Y- % m- %d ' ) ,
} )
2007-03-06 06:23:48 +00:00
return True
def date_next ( self , cr , uid , ids , context ) :
for sheet in self . browse ( cr , uid , ids , context ) :
2007-03-26 13:52:53 +00:00
if DateTime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) > = DateTime . strptime ( sheet . date_to , ' % Y- % m- %d ' ) :
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_to , } )
else :
self . write ( cr , uid , [ sheet . id ] , {
' date_current ' : ( DateTime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) + DateTime . RelativeDateTime ( days = 1 ) ) . strftime ( ' % Y- % m- %d ' ) ,
} )
2007-03-06 06:23:48 +00:00
return True
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
def sign_in ( self , cr , uid , ids , context ) :
2007-04-24 09:57:49 +00:00
if not self . browse ( cr , uid , ids , context ) [ 0 ] . date_current == time . strftime ( ' % Y- % m- %d ' ) :
raise osv . except_osv ( ' Error ! ' , ' You can not sign in from an other date than today ' )
2007-03-06 06:23:48 +00:00
emp_obj = self . pool . get ( ' hr.employee ' )
emp_id = emp_obj . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] )
2007-03-26 13:52:53 +00:00
context [ ' sheet_id ' ] = ids [ 0 ]
success = emp_obj . sign_in ( cr , uid , emp_id , context = context )
2007-03-06 06:23:48 +00:00
return True
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
def sign_out ( self , cr , uid , ids , context ) :
2007-04-24 09:57:49 +00:00
if not self . browse ( cr , uid , ids , context ) [ 0 ] . date_current == time . strftime ( ' % Y- % m- %d ' ) :
raise osv . except_osv ( ' Error ! ' , ' You can not sign out from an other date than today ' )
2007-03-06 06:23:48 +00:00
emp_obj = self . pool . get ( ' hr.employee ' )
emp_id = emp_obj . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] )
2007-03-26 13:52:53 +00:00
context [ ' sheet_id ' ] = ids [ 0 ]
success = emp_obj . sign_out ( cr , uid , emp_id , context = context )
2007-03-06 06:23:48 +00:00
return True
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
_columns = {
' name ' : fields . char ( ' Description ' , size = 64 , select = 1 ) ,
' user_id ' : fields . many2one ( ' res.users ' , ' User ' , required = True , select = 1 ) ,
2007-03-26 13:52:53 +00:00
' date_from ' : fields . date ( ' Date from ' , required = True , select = 1 , readonly = True , states = { ' new ' : [ ( ' readonly ' , False ) ] } ) ,
' date_to ' : fields . date ( ' Date to ' , required = True , select = 1 , readonly = True , states = { ' new ' : [ ( ' readonly ' , False ) ] } ) ,
2007-03-06 06:23:48 +00:00
' date_current ' : fields . date ( ' Current date ' , required = True ) ,
2007-04-24 09:57:49 +00:00
' timesheet_ids ' : one2many_mod ( ' hr.analytic.timesheet ' , ' sheet_id ' , ' Timesheet lines ' , domain = [ ( ' date ' , ' = ' , time . strftime ( ' % Y- % m- %d ' ) ) ] , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] , ' new ' : [ ( ' readonly ' , False ) ] } ) ,
2007-03-26 13:52:53 +00:00
' attendances_ids ' : one2many_mod2 ( ' hr.attendance ' , ' sheet_id ' , ' Attendances ' , readonly = True , states = { ' draft ' : [ ( ' readonly ' , False ) ] , ' new ' : [ ( ' readonly ' , False ) ] } ) ,
' state ' : fields . selection ( [ ( ' new ' , ' New ' ) , ( ' draft ' , ' Draft ' ) , ( ' confirm ' , ' Confirmed ' ) , ( ' done ' , ' Done ' ) ] , ' state ' , select = True , required = True , readonly = True ) ,
2007-03-06 09:55:17 +00:00
' state_attendance ' : fields . function ( _state_attendance , method = True , type = ' selection ' , selection = [ ( ' absent ' , ' Absent ' ) , ( ' present ' , ' Present ' ) , ( ' none ' , ' No employee defined ' ) ] , string = ' Current state ' ) ,
2007-03-06 06:23:48 +00:00
' total_attendance_day ' : fields . function ( _total_attendance_day , method = True , string = ' Total Attendance ' ) ,
' total_timesheet_day ' : fields . function ( _total_timesheet_day , method = True , string = ' Total Timesheet ' ) ,
' total_difference_day ' : fields . function ( _total_difference_day , method = True , string = ' Difference ' ) ,
' total_attendance ' : fields . function ( _total_attendance , method = True , string = ' Total Attendance ' ) ,
' total_timesheet ' : fields . function ( _total_timesheet , method = True , string = ' Total Timesheet ' ) ,
' total_difference ' : fields . function ( _total_difference , method = True , string = ' Difference ' ) ,
' period_ids ' : fields . one2many ( ' hr_timesheet_sheet.sheet.day ' , ' sheet_id ' , ' Period ' , readonly = True ) ,
2007-03-06 09:55:17 +00:00
' account_ids ' : fields . one2many ( ' hr_timesheet_sheet.sheet.account ' , ' sheet_id ' , ' Analytic accounts ' , readonly = True ) ,
2007-03-06 06:23:48 +00:00
}
2007-03-07 06:26:01 +00:00
def _default_date_from ( self , cr , uid , context = { } ) :
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context )
r = user . company_id . timesheet_range
if r == ' month ' :
return time . strftime ( ' % Y- % m-01 ' )
elif r == ' week ' :
return ( DateTime . now ( ) + DateTime . RelativeDateTime ( weekday = ( DateTime . Monday , 0 ) ) ) . strftime ( ' % Y- % m- %d ' )
elif r == ' year ' :
return time . strftime ( ' % Y-01-01 ' )
return time . strftime ( ' % Y- % m- %d ' )
def _default_date_to ( self , cr , uid , context = { } ) :
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context )
r = user . company_id . timesheet_range
if r == ' month ' :
return ( DateTime . now ( ) + DateTime . RelativeDateTime ( months = + 1 , day = 1 , days = - 1 ) ) . strftime ( ' % Y- % m- %d ' )
elif r == ' week ' :
return ( DateTime . now ( ) + DateTime . RelativeDateTime ( weekday = ( DateTime . Sunday , 0 ) ) ) . strftime ( ' % Y- % m- %d ' )
elif r == ' year ' :
return time . strftime ( ' % Y-12-31 ' )
return time . strftime ( ' % Y- % m- %d ' )
2007-03-06 06:23:48 +00:00
_defaults = {
' user_id ' : lambda self , cr , uid , c : uid ,
2007-03-07 06:26:01 +00:00
' date_from ' : _default_date_from ,
' date_current ' : lambda * a : time . strftime ( ' % Y- % m- %d ' ) ,
' date_to ' : _default_date_to ,
2007-03-26 13:52:53 +00:00
' state ' : lambda * a : ' new ' ,
2007-03-06 06:23:48 +00:00
}
2007-04-13 08:44:07 +00:00
def _sheet_date ( self , cr , uid , ids ) :
for sheet in self . browse ( cr , uid , ids ) :
cr . execute ( ' select id from hr_timesheet_sheet_sheet where (date_from< %s and %s <date_to) and user_id= %d and id<> %d ' , ( sheet . date_to , sheet . date_from , sheet . user_id . id , sheet . id ) )
if cr . fetchall ( ) :
return False
return True
_constraints = [
( _sheet_date , ' You can not have 2 timesheets that overlaps ! ' , [ ' date_from ' , ' date_to ' ] )
]
2007-03-05 18:22:32 +00:00
hr_timesheet_sheet ( )
2007-03-26 13:52:53 +00:00
def _get_current_sheet ( self , cr , uid , context = { } ) :
ts = self . pool . get ( ' hr_timesheet_sheet.sheet ' )
ids = ts . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) , ( ' state ' , ' = ' , ' draft ' ) , ( ' date_from ' , ' <= ' , time . strftime ( ' % Y- % m- %d ' ) ) , ( ' date_to ' , ' >= ' , time . strftime ( ' % Y- % m- %d ' ) ) ] )
if ids :
return ids [ 0 ]
return False
2007-03-05 18:22:32 +00:00
class hr_timesheet_line ( osv . osv ) :
2007-03-26 13:52:53 +00:00
_inherit = " hr.analytic.timesheet "
def _get_default_date ( self , cr , uid , context = { } ) :
if ' date ' in context :
return context [ ' date ' ]
return time . strftime ( ' % Y- % m- %d ' )
def _sheet_date ( self , cr , uid , ids ) :
timesheet_lines = self . browse ( cr , uid , ids )
for l in timesheet_lines :
2007-04-16 06:19:24 +00:00
if l . date [ : 10 ] < l . sheet_id . date_from :
2007-03-26 13:52:53 +00:00
return False
2007-04-16 06:19:24 +00:00
if l . date [ : 10 ] > l . sheet_id . date_to :
2007-03-26 13:52:53 +00:00
return False
return True
2007-03-06 06:23:48 +00:00
_columns = {
2007-03-26 13:52:53 +00:00
' sheet_id ' : fields . many2one ( ' hr_timesheet_sheet.sheet ' , ' Sheet ' , ondelete = ' set null ' , required = True , relate = True )
2007-03-06 06:23:48 +00:00
}
2007-03-26 13:52:53 +00:00
_defaults = {
' sheet_id ' : _get_current_sheet ,
' date ' : _get_default_date ,
2007-03-06 06:23:48 +00:00
}
2007-03-26 13:52:53 +00:00
_constraints = [ ( _sheet_date , ' Error: the timesheet line date must be in the sheet \' s dates ' , [ ' date ' ] ) ]
2007-03-06 06:23:48 +00:00
def create ( self , cr , uid , vals , * args , * * kwargs ) :
if ' sheet_id ' in vals :
ts = self . pool . get ( ' hr_timesheet_sheet.sheet ' ) . browse ( cr , uid , vals [ ' sheet_id ' ] )
if ts . state < > ' draft ' :
raise osv . except_osv ( ' Error ! ' , ' You can not modify an entry in a confirmed timesheet ! ' )
return super ( hr_timesheet_line , self ) . create ( cr , uid , vals , * args , * * kwargs )
def unlink ( self , cr , uid , ids , * args , * * kwargs ) :
self . _check ( cr , uid , ids )
return super ( hr_timesheet_line , self ) . unlink ( cr , uid , ids , * args , * * kwargs )
def write ( self , cr , uid , ids , * args , * * kwargs ) :
self . _check ( cr , uid , ids )
return super ( hr_timesheet_line , self ) . write ( cr , uid , ids , * args , * * kwargs )
def _check ( self , cr , uid , ids ) :
for att in self . browse ( cr , uid , ids ) :
if att . sheet_id and att . sheet_id . state < > ' draft ' :
raise osv . except_osv ( ' Error ! ' , ' You can not modify an entry in a confirmed timesheet ! ' )
return True
2007-03-05 18:22:32 +00:00
hr_timesheet_line ( )
class hr_attendance ( osv . osv ) :
2007-03-06 06:23:48 +00:00
_inherit = " hr.attendance "
2007-03-26 13:52:53 +00:00
def _get_default_date ( self , cr , uid , context = { } ) :
if ' name ' in context :
return context [ ' name ' ] + time . strftime ( ' % H: % M: % S ' )
return time . strftime ( ' % Y- % m- %d % H: % M: % S ' )
def _sheet_date ( self , cr , uid , ids ) :
attendances = self . browse ( cr , uid , ids )
for att in attendances :
2007-04-16 06:19:24 +00:00
if att . name [ : 10 ] < att . sheet_id . date_from :
2007-03-26 13:52:53 +00:00
return False
2007-04-16 06:19:24 +00:00
if att . name [ : 10 ] > att . sheet_id . date_to :
2007-03-26 13:52:53 +00:00
return False
return True
2007-03-06 06:23:48 +00:00
_columns = {
2007-03-26 13:52:53 +00:00
' sheet_id ' : fields . many2one ( ' hr_timesheet_sheet.sheet ' , ' Sheet ' , ondelete = ' set null ' , required = True , relate = True )
2007-03-06 06:23:48 +00:00
}
2007-03-26 13:52:53 +00:00
_defaults = {
' sheet_id ' : _get_current_sheet ,
' name ' : _get_default_date ,
2007-03-06 06:23:48 +00:00
}
2007-03-26 13:52:53 +00:00
_constraints = [ ( _sheet_date , ' Error: the attendance date must be in the sheet \' s dates ' , [ ' name ' ] ) ]
def create ( self , cr , uid , vals , context = { } ) :
if ' sheet_id ' in context :
vals [ ' sheet_id ' ] = context [ ' sheet_id ' ]
2007-03-06 06:23:48 +00:00
if ' sheet_id ' in vals :
ts = self . pool . get ( ' hr_timesheet_sheet.sheet ' ) . browse ( cr , uid , vals [ ' sheet_id ' ] )
if ts . state < > ' draft ' :
raise osv . except_osv ( ' Error ! ' , ' You can not modify an entry in a confirmed timesheet ! ' )
2007-03-26 13:52:53 +00:00
return super ( hr_attendance , self ) . create ( cr , uid , vals , context = context )
2007-03-06 06:23:48 +00:00
def unlink ( self , cr , uid , ids , * args , * * kwargs ) :
self . _check ( cr , uid , ids )
return super ( hr_attendance , self ) . unlink ( cr , uid , ids , * args , * * kwargs )
2007-03-26 13:52:53 +00:00
def write ( self , cr , uid , ids , vals , context = { } ) :
if ' sheet_id ' in context :
vals [ ' sheet_id ' ] = context [ ' sheet_id ' ]
2007-03-06 06:23:48 +00:00
self . _check ( cr , uid , ids )
2007-03-26 13:52:53 +00:00
return super ( hr_attendance , self ) . write ( cr , uid , ids , vals , context = context )
2007-03-06 06:23:48 +00:00
def _check ( self , cr , uid , ids ) :
for att in self . browse ( cr , uid , ids ) :
if att . sheet_id and att . sheet_id . state < > ' draft ' :
raise osv . except_osv ( ' Error ! ' , ' You can not modify an entry in a confirmed timesheet ! ' )
return True
2007-03-05 18:22:32 +00:00
hr_attendance ( )
class hr_timesheet_sheet_sheet_day ( osv . osv ) :
2007-03-06 06:23:48 +00:00
_name = " hr_timesheet_sheet.sheet.day "
_description = " Timesheets by period "
_auto = False
def _total_difference ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
result [ day . id ] = day . total_attendance - day . total_timesheet
return result
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
def _total_attendance ( self , cr , uid , ids , name , args , context ) :
result = { }
for day in self . browse ( cr , uid , ids , context ) :
2007-04-24 10:53:41 +00:00
cr . execute ( ' select name,action from hr_attendance where name>= %s and name<= %s and sheet_id= %d and action in ( \' sign_in \' , \' sign_out \' ) order by name ' , ( day . name , day . name + ' 23:59:59 ' , day . sheet_id ) )
2007-03-06 06:23:48 +00:00
attendences = cr . dictfetchall ( )
wh = 0
if attendences and attendences [ 0 ] [ ' action ' ] == ' sign_out ' :
attendences . insert ( 0 , { ' name ' : day . name + ' 00:00:00 ' , ' action ' : ' sign_in ' } )
if attendences and attendences [ - 1 ] [ ' action ' ] == ' sign_in ' :
2007-03-06 09:55:17 +00:00
if day . name == time . strftime ( ' % Y- % m- %d ' ) :
attendences . append ( { ' name ' : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) , ' action ' : ' sign_out ' } )
else :
attendences . append ( { ' name ' : day . name + ' 23:59:59 ' , ' action ' : ' sign_out ' } )
2007-03-06 06:23:48 +00:00
for att in attendences :
dt = DateTime . strptime ( att [ ' name ' ] , ' % Y- % m- %d % H: % M: % S ' )
if att [ ' action ' ] == ' sign_out ' :
wh + = ( dt - ldt ) . hours
ldt = dt
2007-03-06 09:55:17 +00:00
result [ day . id ] = round ( wh , 2 )
2007-03-06 06:23:48 +00:00
return result
_order = ' name '
_columns = {
' name ' : fields . date ( ' Date ' , readonly = True ) ,
' sheet_id ' : fields . many2one ( ' hr_timesheet_sheet.sheet ' , ' Sheet ' , readonly = True , select = " 1 " ) ,
' total_timesheet ' : fields . float ( ' Project Timesheet ' , readonly = True ) ,
' total_attendance ' : fields . function ( _total_attendance , method = True , string = ' Attendance ' , readonly = True ) ,
' total_difference ' : fields . function ( _total_difference , method = True , string = ' Difference ' , readonly = True ) ,
}
def init ( self , cr ) :
cr . execute ( """ create or replace view hr_timesheet_sheet_sheet_day as
(
select
2007-03-26 13:52:53 +00:00
min ( hrt . id ) as id ,
2007-03-06 06:23:48 +00:00
l . date as name ,
2007-03-26 13:52:53 +00:00
hrt . sheet_id as sheet_id ,
2007-03-06 06:23:48 +00:00
sum ( l . unit_amount ) as total_timesheet
from
2007-03-26 13:52:53 +00:00
hr_analytic_timesheet hrt
left join account_analytic_line l on ( l . id = hrt . line_id )
group by l . date , hrt . sheet_id
2007-03-06 06:23:48 +00:00
) union (
select
min ( a . oid ) as id ,
a . name : : date as name ,
a . sheet_id as sheet_id ,
0.0 as total_timesheet
from
hr_attendance a
where a . name : : date not in ( select distinct date from account_analytic_line )
group by a . name : : date , a . sheet_id
) """ )
2007-03-05 18:22:32 +00:00
hr_timesheet_sheet_sheet_day ( )
2007-03-06 09:55:17 +00:00
class hr_timesheet_sheet_sheet_account ( osv . osv ) :
_name = " hr_timesheet_sheet.sheet.account "
_description = " Timesheets by period "
_auto = False
_order = ' name '
_columns = {
' name ' : fields . many2one ( ' account.analytic.account ' , ' Analytic Account ' , readonly = True ) ,
' sheet_id ' : fields . many2one ( ' hr_timesheet_sheet.sheet ' , ' Sheet ' , readonly = True , relate = True ) ,
' total ' : fields . float ( ' Total Time ' , digits = ( 16 , 2 ) , readonly = True ) ,
2007-04-17 10:16:29 +00:00
' invoice_rate ' : fields . many2one ( ' hr_timesheet_invoice.factor ' , ' Invoice rate ' , readonly = True ) ,
2007-03-06 09:55:17 +00:00
}
def init ( self , cr ) :
cr . execute ( """ create or replace view hr_timesheet_sheet_sheet_account as (
select
2007-03-26 13:52:53 +00:00
min ( hrt . id ) as id ,
l . account_id as name ,
hrt . sheet_id as sheet_id ,
2007-04-17 10:16:29 +00:00
sum ( l . unit_amount ) as total ,
l . to_invoice as invoice_rate
2007-03-06 09:55:17 +00:00
from
2007-03-26 13:52:53 +00:00
hr_analytic_timesheet hrt
left join account_analytic_line l on ( l . id = hrt . line_id )
2007-04-17 10:16:29 +00:00
group by l . account_id , hrt . sheet_id , l . to_invoice
2007-03-06 09:55:17 +00:00
) """ )
hr_timesheet_sheet_sheet_account ( )
class res_company ( osv . osv ) :
_inherit = ' res.company '
_columns = {
2007-03-07 06:26:01 +00:00
' timesheet_range ' : fields . selection ( [ ( ' day ' , ' Day ' ) , ( ' week ' , ' Week ' ) , ( ' month ' , ' Month ' ) , ( ' year ' , ' Year ' ) ] , ' Timeshet range ' , required = True ) ,
' timesheet_max_difference ' : fields . float ( ' Timesheet allowed difference ' , help = " Allowed difference between the sign in/out and the timesheet computation for one sheet. Set this to 0 if you do not want any control. " ) ,
2007-03-06 09:55:17 +00:00
}
_defaults = {
' timesheet_range ' : lambda * args : ' month ' ,
2007-03-07 06:26:01 +00:00
' timesheet_max_difference ' : lambda * args : 0.0
2007-03-06 09:55:17 +00:00
}
res_company ( )