2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2007-03-05 18:22:32 +00:00
##############################################################################
2009-12-24 07:05:23 +00:00
#
2009-10-14 11:15:34 +00:00
# OpenERP, Open Source Management Solution
2010-01-12 09:18:39 +00:00
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
2007-03-05 18:22:32 +00:00
#
2008-11-03 19:18:56 +00:00
# This program is free software: you can redistribute it and/or modify
2009-10-14 11:15:34 +00:00
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
2007-03-05 18:22:32 +00:00
#
2008-11-03 19:18:56 +00:00
# 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
2009-10-14 11:15:34 +00:00
# GNU Affero General Public License for more details.
2007-03-05 18:22:32 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2009-12-24 07:05:23 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2007-03-05 18:22:32 +00:00
#
##############################################################################
import time
2010-10-15 14:01:53 +00:00
from datetime import datetime
from dateutil . relativedelta import relativedelta
2010-11-02 11:11:12 +00:00
from osv import fields , osv
2008-07-08 08:13:12 +00:00
from tools . translate import _
2010-11-02 11:11:12 +00:00
import netsvc
2007-03-05 18:22:32 +00:00
2007-03-06 06:23:48 +00:00
class one2many_mod2 ( fields . one2many ) :
2010-09-21 13:07:39 +00:00
def get ( self , cr , obj , ids , name , user = None , offset = 0 , context = None , values = None ) :
if context is None :
context = { }
2008-07-22 15:11:28 +00:00
2010-09-21 13:07:39 +00:00
if values is None :
values = { }
2008-07-22 15:11:28 +00:00
2010-09-21 13:07:39 +00:00
# dict:
# {idn: (date_current, user_id), ...
# 1: ('2010-08-15', 1)}
res6 = dict ( [ ( rec [ ' id ' ] , ( rec [ ' date_current ' ] , rec [ ' user_id ' ] [ 0 ] ) )
for rec
in obj . read ( cr , user , ids , [ ' date_current ' , ' user_id ' ] , context = context ) ] )
# eg: ['|', '|',
# '&', '&', ('name', '>=', '2011-03-01'), ('name', '<=', '2011-03-01'), ('employee_id.user_id', '=', 1),
# '&', '&', ('name', '>=', '2011-02-01'), ('name', '<=', '2011-02-01'), ('employee_id.user_id', '=', 1)]
dom = [ ]
for c , id in enumerate ( ids ) :
2008-07-22 15:11:28 +00:00
if id in res6 :
2010-09-21 13:07:39 +00:00
if c : # skip first
dom . insert ( 0 , ' | ' )
dom . append ( ' & ' )
dom . append ( ' & ' )
dom . append ( ( ' name ' , ' >= ' , res6 [ id ] [ 0 ] ) )
dom . append ( ( ' name ' , ' <= ' , res6 [ id ] [ 0 ] ) )
dom . append ( ( ' employee_id.user_id ' , ' = ' , res6 [ id ] [ 1 ] ) )
2008-07-22 15:11:28 +00:00
2010-09-21 13:07:39 +00:00
ids2 = obj . pool . get ( self . _obj ) . search ( cr , user , dom , limit = self . _limit )
2010-09-22 08:38:38 +00:00
res = { }
for i in ids :
res [ i ] = [ ]
2010-09-21 13:07:39 +00:00
for r in obj . pool . get ( self . _obj ) . _read_flat ( cr , user , ids2 , [ self . _fields_id ] , context = context , load = ' _classic_write ' ) :
2008-07-22 15:11:28 +00:00
if r [ self . _fields_id ] :
2010-09-22 08:38:38 +00:00
res [ r [ self . _fields_id ] [ 0 ] ] . append ( r [ ' id ' ] )
2008-07-22 15:11:28 +00:00
return res
def set ( self , cr , obj , id , field , values , user = None , context = None ) :
if context is None :
context = { }
2010-09-21 13:07:39 +00:00
2008-07-22 15:11:28 +00:00
context = context . copy ( )
context [ ' sheet_id ' ] = id
2010-09-21 13:07:39 +00:00
return super ( one2many_mod2 , self ) . set ( cr , obj , id , field , values , user = user , context = context )
2008-01-18 14:49:43 +00:00
2007-03-06 06:23:48 +00:00
class one2many_mod ( fields . one2many ) :
2010-09-21 13:07:39 +00:00
def get ( self , cr , obj , ids , name , user = None , offset = 0 , context = None , values = None ) :
if context is None :
context = { }
if values is None :
values = { }
2008-07-22 15:11:28 +00:00
2010-05-19 13:07:03 +00:00
res5 = obj . read ( cr , user , ids , [ ' date_current ' , ' user_id ' ] , context = context )
2008-07-22 15:11:28 +00:00
res6 = { }
for r in res5 :
res6 [ r [ ' id ' ] ] = ( r [ ' date_current ' ] , r [ ' user_id ' ] [ 0 ] )
ids2 = [ ]
for id in ids :
dom = [ ]
if id in res6 :
dom = [ ( ' date ' , ' = ' , res6 [ id ] [ 0 ] ) , ( ' user_id ' , ' = ' , res6 [ id ] [ 1 ] ) ]
ids2 . extend ( obj . pool . get ( self . _obj ) . search ( cr , user ,
dom , limit = self . _limit ) )
2010-09-22 08:38:38 +00:00
res = { }
for i in ids :
res [ i ] = [ ]
2008-07-22 15:11:28 +00:00
for r in obj . pool . get ( self . _obj ) . _read_flat ( cr , user , ids2 ,
[ self . _fields_id ] , context = context , load = ' _classic_write ' ) :
if r [ self . _fields_id ] :
2010-09-22 08:38:38 +00:00
res [ r [ self . _fields_id ] [ 0 ] ] . append ( r [ ' id ' ] )
2008-07-22 15:11:28 +00:00
return res
2007-03-05 18:22:32 +00:00
class hr_timesheet_sheet ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " hr_timesheet_sheet.sheet "
_table = ' hr_timesheet_sheet_sheet '
_order = " id desc "
2010-09-01 12:04:41 +00:00
_description = " Timesheet "
2008-07-22 15:11:28 +00:00
2010-07-21 12:39:48 +00:00
def _total_day ( self , cr , uid , ids , name , args , context = None ) :
2009-09-24 10:46:21 +00:00
res = { }
cr . execute ( ' SELECT sheet.id, day.total_attendance, day.total_timesheet, day.total_difference \
2008-07-22 15:11:28 +00:00
FROM hr_timesheet_sheet_sheet AS sheet \
LEFT JOIN hr_timesheet_sheet_sheet_day AS day \
ON ( sheet . id = day . sheet_id \
AND day . name = sheet . date_current ) \
2010-06-10 13:34:19 +00:00
WHERE sheet . id IN % s ' ,(tuple(ids),))
2009-09-24 10:46:21 +00:00
for record in cr . fetchall ( ) :
res [ record [ 0 ] ] = { }
res [ record [ 0 ] ] [ ' total_attendance_day ' ] = record [ 1 ]
res [ record [ 0 ] ] [ ' total_timesheet_day ' ] = record [ 2 ]
res [ record [ 0 ] ] [ ' total_difference_day ' ] = record [ 3 ]
return res
2008-07-22 15:11:28 +00:00
2010-05-19 13:07:03 +00:00
def _total ( self , cr , uid , ids , name , args , context = None ) :
2009-09-24 10:46:21 +00:00
res = { }
cr . execute ( ' SELECT s.id, COALESCE(SUM(d.total_attendance),0), COALESCE(SUM(d.total_timesheet),0), COALESCE(SUM(d.total_difference),0) \
2008-07-22 15:11:28 +00:00
FROM hr_timesheet_sheet_sheet s \
LEFT JOIN hr_timesheet_sheet_sheet_day d \
ON ( s . id = d . sheet_id ) \
2010-06-10 13:34:19 +00:00
WHERE s . id IN % s GROUP BY s . id ' ,(tuple(ids),))
2009-09-24 10:46:21 +00:00
for record in cr . fetchall ( ) :
res [ record [ 0 ] ] = { }
res [ record [ 0 ] ] [ ' total_attendance ' ] = record [ 1 ]
res [ record [ 0 ] ] [ ' total_timesheet ' ] = record [ 2 ]
res [ record [ 0 ] ] [ ' total_difference ' ] = record [ 3 ]
return res
2008-07-22 15:11:28 +00:00
2010-05-19 13:07:03 +00:00
def _state_attendance ( self , cr , uid , ids , name , args , context = None ) :
emp_obj = self . pool . get ( ' hr.employee ' )
2008-07-22 15:11:28 +00:00
result = { }
link_emp = { }
emp_ids = [ ]
2010-05-19 13:07:03 +00:00
for sheet in self . browse ( cr , uid , ids , context = context ) :
2008-07-22 15:11:28 +00:00
result [ sheet . id ] = ' none '
emp_ids2 = emp_obj . search ( cr , uid ,
2010-07-27 07:11:45 +00:00
[ ( ' user_id ' , ' = ' , sheet . user_id . id ) ] , context = context )
2008-07-22 15:11:28 +00:00
if emp_ids2 :
link_emp [ emp_ids2 [ 0 ] ] = sheet . id
emp_ids . append ( emp_ids2 [ 0 ] )
for emp in emp_obj . browse ( cr , uid , emp_ids , context = context ) :
if emp . id in link_emp :
sheet_id = link_emp [ emp . id ]
result [ sheet_id ] = emp . state
return result
2010-09-01 12:04:41 +00:00
2010-08-11 15:58:57 +00:00
def check_employee_attendance_state ( self , cr , uid , sheet_id , context = None ) :
ids_signin = self . pool . get ( ' hr.attendance ' ) . search ( cr , uid , [ ( ' sheet_id ' , ' = ' , sheet_id ) , ( ' action ' , ' = ' , ' sign_in ' ) ] )
ids_signout = self . pool . get ( ' hr.attendance ' ) . search ( cr , uid , [ ( ' sheet_id ' , ' = ' , sheet_id ) , ( ' action ' , ' = ' , ' sign_out ' ) ] )
if len ( ids_signin ) != len ( ids_signout ) :
raise osv . except_osv ( ( ' Warning ! ' ) , _ ( ' The timesheet cannot be validated as it does not contain equal no. of sign ins and sign outs! ' ) )
return True
2008-07-22 15:11:28 +00:00
2009-01-15 16:57:02 +00:00
def copy ( self , cr , uid , ids , * args , * * argv ) :
2010-08-11 15:58:57 +00:00
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot duplicate a timesheet ! ' ) )
2009-01-15 16:57:02 +00:00
2010-10-06 16:39:01 +00:00
def create ( self , cr , uid , vals , * args , * * argv ) :
if ' employee_id ' in vals :
if not self . pool . get ( ' hr.employee ' ) . browse ( cr , uid , vals [ ' employee_id ' ] ) . user_id :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot create a timesheet for an employee that does not have any user defined ! ' ) )
2011-03-14 09:10:03 +00:00
if not self . pool . get ( ' hr.employee ' ) . browse ( cr , uid , vals [ ' employee_id ' ] ) . product_id :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot create a timesheet for an employee that does not have any product defined ! ' ) )
if not self . pool . get ( ' hr.employee ' ) . browse ( cr , uid , vals [ ' employee_id ' ] ) . journal_id :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot create a timesheet for an employee that does not have any analytic journal defined ! ' ) )
2010-10-06 16:39:01 +00:00
return super ( hr_timesheet_sheet , self ) . create ( cr , uid , vals , * args , * * argv )
def write ( self , cr , uid , ids , vals , * args , * * argv ) :
if ' employee_id ' in vals :
new_user_id = self . pool . get ( ' hr.employee ' ) . browse ( cr , uid , vals [ ' employee_id ' ] ) . user_id . id or False
if not new_user_id :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot create a timesheet for an employee that does not have any user defined ! ' ) )
if not self . _sheet_date ( cr , uid , ids , forced_user_id = new_user_id ) :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You can not have 2 timesheets that overlaps ! \n Please use the menu \' My Current Timesheet \' to avoid this problem. ' ) )
2011-03-14 09:38:54 +00:00
if not self . pool . get ( ' hr.employee ' ) . browse ( cr , uid , vals [ ' employee_id ' ] ) . product_id :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot create a timesheet for an employee that does not have any product defined ! ' ) )
if not self . pool . get ( ' hr.employee ' ) . browse ( cr , uid , vals [ ' employee_id ' ] ) . journal_id :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot create a timesheet for an employee that does not have any analytic journal defined ! ' ) )
2010-10-06 16:39:01 +00:00
return super ( hr_timesheet_sheet , self ) . write ( cr , uid , ids , vals , * args , * * argv )
2010-05-19 13:07:03 +00:00
def button_confirm ( self , cr , uid , ids , context = None ) :
for sheet in self . browse ( cr , uid , ids , context = context ) :
2010-08-11 15:58:57 +00:00
self . check_employee_attendance_state ( cr , uid , sheet . id , context )
2008-07-22 15:11:28 +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
2010-05-19 13:07:03 +00:00
def date_today ( self , cr , uid , ids , context = None ) :
for sheet in self . browse ( cr , uid , ids , context = context ) :
2010-10-15 14:01:53 +00:00
if datetime . today ( ) < = datetime . strptime ( sheet . date_from , ' % Y- % m- %d ' ) :
2010-07-27 07:11:45 +00:00
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_from , } , context = context )
2010-10-15 14:01:53 +00:00
elif datetime . now ( ) > = datetime . strptime ( sheet . date_to , ' % Y- % m- %d ' ) :
2010-07-27 07:11:45 +00:00
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_to , } , context = context )
2008-07-22 15:11:28 +00:00
else :
2010-07-27 07:11:45 +00:00
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : time . strftime ( ' % Y- % m- %d ' ) } , context = context )
2008-07-22 15:11:28 +00:00
return True
2010-05-19 13:07:03 +00:00
def date_previous ( self , cr , uid , ids , context = None ) :
for sheet in self . browse ( cr , uid , ids , context = context ) :
2010-10-15 14:01:53 +00:00
if datetime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) < = datetime . strptime ( sheet . date_from , ' % Y- % m- %d ' ) :
2010-07-27 07:11:45 +00:00
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_from , } , context = context )
2008-07-22 15:11:28 +00:00
else :
self . write ( cr , uid , [ sheet . id ] , {
2010-10-15 14:01:53 +00:00
' date_current ' : ( datetime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) + relativedelta ( days = - 1 ) ) . strftime ( ' % Y- % m- %d ' ) ,
2010-07-27 07:11:45 +00:00
} , context = context )
2008-07-22 15:11:28 +00:00
return True
2010-05-19 13:07:03 +00:00
def date_next ( self , cr , uid , ids , context = None ) :
for sheet in self . browse ( cr , uid , ids , context = context ) :
2010-10-15 14:01:53 +00:00
if datetime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) > = datetime . strptime ( sheet . date_to , ' % Y- % m- %d ' ) :
2010-07-27 07:11:45 +00:00
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_to , } , context = context )
2008-07-22 15:11:28 +00:00
else :
self . write ( cr , uid , [ sheet . id ] , {
2010-10-15 14:01:53 +00:00
' date_current ' : ( datetime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) + relativedelta ( days = 1 ) ) . strftime ( ' % Y- % m- %d ' ) ,
2010-07-27 07:11:45 +00:00
} , context = context )
2008-07-22 15:11:28 +00:00
return True
2010-05-19 13:07:03 +00:00
def button_dummy ( self , cr , uid , ids , context = None ) :
for sheet in self . browse ( cr , uid , ids , context = context ) :
2010-10-15 14:01:53 +00:00
if datetime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) < = datetime . strptime ( sheet . date_from , ' % Y- % m- %d ' ) :
2010-07-27 07:11:45 +00:00
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_from , } , context = context )
2010-10-15 14:01:53 +00:00
elif datetime . strptime ( sheet . date_current , ' % Y- % m- %d ' ) > = datetime . strptime ( sheet . date_to , ' % Y- % m- %d ' ) :
2010-07-27 07:11:45 +00:00
self . write ( cr , uid , [ sheet . id ] , { ' date_current ' : sheet . date_to , } , context = context )
2008-07-22 15:11:28 +00:00
return True
2011-07-06 07:47:31 +00:00
def check_sign ( self , cr , uid , ids , typ , context = None ) :
2010-12-29 12:39:00 +00:00
sheet = self . browse ( cr , uid , ids , context = context ) [ 0 ]
if not sheet . date_current == time . strftime ( ' % Y- % m- %d ' ) :
2011-04-20 12:55:21 +00:00
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot sign in/sign out from an other date than today ' ) )
2008-07-22 15:11:28 +00:00
return True
2011-07-06 07:47:31 +00:00
def sign ( self , cr , uid , ids , typ , context = None ) :
self . check_sign ( cr , uid , ids , typ , context = context )
sign_obj = self . pool . get ( ' hr.sign.in.out ' )
sign_id = sign_obj . create ( cr , uid , { } , context = context )
methods = { ' sign_in ' : sign_obj . si_check ,
' sign_out ' : sign_obj . so_check }
wizard_result = methods [ typ ] ( cr , uid , [ sign_id ] , context = context )
if wizard_result . get ( ' type ' , False ) == ' ir.actions.act_window_close ' :
return True # ensure we do not close the main window !
wizard_result [ ' nodestroy ' ] = True # do not destroy the main window !
return wizard_result
2010-12-29 12:39:00 +00:00
def sign_in ( self , cr , uid , ids , context = None ) :
2011-07-06 07:47:31 +00:00
return self . sign ( cr , uid , ids , ' sign_in ' , context = context )
2010-12-29 12:39:00 +00:00
2010-05-19 13:07:03 +00:00
def sign_out ( self , cr , uid , ids , context = None ) :
2011-07-06 07:47:31 +00:00
return self . sign ( cr , uid , ids , ' sign_out ' , context = context )
2008-07-22 15:11:28 +00:00
_columns = {
2009-12-24 07:05:23 +00:00
' name ' : fields . char ( ' Description ' , size = 64 , select = 1 ,
2009-01-20 18:51:08 +00:00
states = { ' confirm ' : [ ( ' readonly ' , True ) ] , ' done ' : [ ( ' readonly ' , True ) ] } ) ,
2010-10-06 16:39:01 +00:00
' employee_id ' : fields . many2one ( ' hr.employee ' , ' Employee ' , required = True ) ,
' user_id ' : fields . related ( ' employee_id ' , ' user_id ' , type = " many2one " , relation = " res.users " , store = True , string = " User " , required = False , readonly = True ) , #fields.many2one('res.users', 'User', required=True, select=1, states={'confirm':[('readonly', True)], 'done':[('readonly', True)]}),
2008-07-22 15:11:28 +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 ) ] } ) ,
2011-01-17 11:20:56 +00:00
' date_current ' : fields . date ( ' Current date ' , required = True , select = 1 ) ,
2008-07-22 15:11:28 +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 ) ] }
) ,
2011-03-11 17:25:13 +00:00
' attendances_ids ' : one2many_mod2 ( ' hr.attendance ' , ' sheet_id ' , ' Attendances ' ) ,
2009-12-24 07:05:23 +00:00
' state ' : fields . selection ( [
( ' new ' , ' New ' ) ,
( ' draft ' , ' Draft ' ) ,
( ' confirm ' , ' Confirmed ' ) ,
( ' done ' , ' Done ' ) ] , ' State ' , select = True , required = True , readonly = True ,
help = ' * The \' Draft \' state is used when a user is encoding a new and unconfirmed timesheet. \
\n * The \' Confirmed \' state is used for to confirm the timesheet by user. \
\n * The \' Done \' state is used when users timesheet is accepted by his/her senior. ' ) ,
2011-07-01 23:41:24 +00:00
' state_attendance ' : fields . function ( _state_attendance , type = ' selection ' , selection = [ ( ' absent ' , ' Absent ' ) , ( ' present ' , ' Present ' ) , ( ' none ' , ' No employee defined ' ) ] , string = ' Current Status ' ) ,
' total_attendance_day ' : fields . function ( _total_day , string = ' Total Attendance ' , multi = " _total_day " ) ,
' total_timesheet_day ' : fields . function ( _total_day , string = ' Total Timesheet ' , multi = " _total_day " ) ,
' total_difference_day ' : fields . function ( _total_day , string = ' Difference ' , multi = " _total_day " ) ,
' total_attendance ' : fields . function ( _total , string = ' Total Attendance ' , multi = " _total_sheet " ) ,
' total_timesheet ' : fields . function ( _total , string = ' Total Timesheet ' , multi = " _total_sheet " ) ,
' total_difference ' : fields . function ( _total , string = ' Difference ' , multi = " _total_sheet " ) ,
2008-07-22 15:11:28 +00:00
' period_ids ' : fields . one2many ( ' hr_timesheet_sheet.sheet.day ' , ' sheet_id ' , ' Period ' , readonly = True ) ,
' account_ids ' : fields . one2many ( ' hr_timesheet_sheet.sheet.account ' , ' sheet_id ' , ' Analytic accounts ' , readonly = True ) ,
2009-11-10 12:49:20 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' ) ,
2010-02-17 08:49:38 +00:00
' department_id ' : fields . many2one ( ' hr.department ' , ' Department ' ) ,
2008-07-22 15:11:28 +00:00
}
2010-07-27 07:11:45 +00:00
def _default_date_from ( self , cr , uid , context = None ) :
2010-05-19 13:07:03 +00:00
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
2008-07-22 15:11:28 +00:00
r = user . company_id and user . company_id . timesheet_range or ' month '
if r == ' month ' :
return time . strftime ( ' % Y- % m-01 ' )
elif r == ' week ' :
2010-10-20 13:29:48 +00:00
return ( datetime . today ( ) + relativedelta ( weekday = 0 , weeks = - 1 ) ) . strftime ( ' % Y- % m- %d ' )
2008-07-22 15:11:28 +00:00
elif r == ' year ' :
return time . strftime ( ' % Y-01-01 ' )
return time . strftime ( ' % Y- % m- %d ' )
2010-07-27 07:11:45 +00:00
def _default_date_to ( self , cr , uid , context = None ) :
2010-05-19 13:07:03 +00:00
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context = context )
2008-07-22 15:11:28 +00:00
r = user . company_id and user . company_id . timesheet_range or ' month '
if r == ' month ' :
2010-10-15 14:01:53 +00:00
return ( datetime . today ( ) + relativedelta ( months = + 1 , day = 1 , days = - 1 ) ) . strftime ( ' % Y- % m- %d ' )
2008-07-22 15:11:28 +00:00
elif r == ' week ' :
2010-10-15 14:01:53 +00:00
return ( datetime . today ( ) + relativedelta ( weekday = 6 ) ) . strftime ( ' % Y- % m- %d ' )
2008-07-22 15:11:28 +00:00
elif r == ' year ' :
return time . strftime ( ' % Y-12-31 ' )
return time . strftime ( ' % Y- % m- %d ' )
2010-10-13 12:00:39 +00:00
def _default_employee ( self , cr , uid , context = None ) :
emp_ids = self . pool . get ( ' hr.employee ' ) . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] , context = context )
return emp_ids and emp_ids [ 0 ] or False
2008-07-22 15:11:28 +00:00
_defaults = {
' date_from ' : _default_date_from ,
' date_current ' : lambda * a : time . strftime ( ' % Y- % m- %d ' ) ,
' date_to ' : _default_date_to ,
2010-05-19 13:07:03 +00:00
' state ' : ' new ' ,
2010-10-13 12:00:39 +00:00
' employee_id ' : _default_employee ,
2010-10-06 16:39:01 +00:00
' company_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' hr_timesheet_sheet.sheet ' , context = c )
2008-07-22 15:11:28 +00:00
}
2010-11-19 13:48:01 +00:00
def _sheet_date ( self , cr , uid , ids , forced_user_id = False , context = None ) :
for sheet in self . browse ( cr , uid , ids , context = context ) :
2010-10-06 16:39:01 +00:00
new_user_id = forced_user_id or sheet . user_id and sheet . user_id . id
if new_user_id :
cr . execute ( ' SELECT id \
2008-07-22 15:11:28 +00:00
FROM hr_timesheet_sheet_sheet \
WHERE ( date_from < % s and % s < date_to ) \
2008-12-10 14:29:55 +00:00
AND user_id = % s \
2010-10-06 16:39:01 +00:00
AND id < > % s ' ,(sheet.date_to, sheet.date_from, new_user_id, sheet.id))
if cr . fetchall ( ) :
return False
2008-07-22 15:11:28 +00:00
return True
2010-11-19 13:48:01 +00:00
def _date_current_check ( self , cr , uid , ids , context = None ) :
for sheet in self . browse ( cr , uid , ids , context = context ) :
2008-08-19 09:15:24 +00:00
if sheet . date_current < sheet . date_from or sheet . date_current > sheet . date_to :
return False
return True
2008-07-22 15:11:28 +00:00
_constraints = [
2008-10-27 15:29:13 +00:00
( _sheet_date , ' You can not have 2 timesheets that overlaps ! \n Please use the menu \' My Current Timesheet \' to avoid this problem. ' , [ ' date_from ' , ' date_to ' ] ) ,
2010-05-19 13:07:03 +00:00
( _date_current_check , ' You must select a Current date which is in the timesheet dates ! ' , [ ' date_current ' ] ) ,
2008-07-22 15:11:28 +00:00
]
def action_set_to_draft ( self , cr , uid , ids , * args ) :
self . write ( cr , uid , ids , { ' state ' : ' draft ' } )
wf_service = netsvc . LocalService ( ' workflow ' )
for id in ids :
wf_service . trg_create ( uid , self . _name , id , cr )
return True
2010-07-27 07:11:45 +00:00
def name_get ( self , cr , uid , ids , context = None ) :
2008-07-22 15:11:28 +00:00
if not len ( ids ) :
return [ ]
return [ ( r [ ' id ' ] , r [ ' date_from ' ] + ' - ' + r [ ' date_to ' ] ) \
for r in self . read ( cr , uid , ids , [ ' date_from ' , ' date_to ' ] ,
2010-07-27 07:11:45 +00:00
context = context , load = ' _classic_write ' ) ]
2007-07-09 09:08:41 +00:00
2009-01-20 20:32:58 +00:00
def unlink ( self , cr , uid , ids , context = None ) :
2010-07-27 07:11:45 +00:00
sheets = self . read ( cr , uid , ids , [ ' state ' , ' total_attendance ' ] , context = context )
2009-12-21 13:00:04 +00:00
for sheet in sheets :
if sheet [ ' state ' ] in ( ' confirm ' , ' done ' ) :
raise osv . except_osv ( _ ( ' Invalid action ! ' ) , _ ( ' Cannot delete Sheet(s) which are already confirmed ! ' ) )
elif sheet [ ' total_attendance ' ] < > 0.00 :
raise osv . except_osv ( _ ( ' Invalid action ! ' ) , _ ( ' Cannot delete Sheet(s) which have attendance entries encoded ! ' ) )
2009-01-20 20:32:58 +00:00
return super ( hr_timesheet_sheet , self ) . unlink ( cr , uid , ids , context = context )
2007-03-05 18:22:32 +00:00
hr_timesheet_sheet ( )
2007-03-26 13:52:53 +00:00
2007-03-05 18:22:32 +00:00
class hr_timesheet_line ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_inherit = " hr.analytic.timesheet "
2010-07-27 07:11:45 +00:00
def _get_default_date ( self , cr , uid , context = None ) :
if context is None :
context = { }
2008-07-22 15:11:28 +00:00
if ' date ' in context :
return context [ ' date ' ]
return time . strftime ( ' % Y- % m- %d ' )
2010-07-27 07:11:45 +00:00
def _sheet ( self , cursor , user , ids , name , args , context = None ) :
2008-07-22 15:11:28 +00:00
sheet_obj = self . pool . get ( ' hr_timesheet_sheet.sheet ' )
cursor . execute ( ' SELECT l.id, COALESCE(MAX(s.id), 0) \
FROM hr_timesheet_sheet_sheet s \
LEFT JOIN ( hr_analytic_timesheet l \
LEFT JOIN account_analytic_line al \
ON ( l . line_id = al . id ) ) \
ON ( s . date_to > = al . date \
AND s . date_from < = al . date \
AND s . user_id = al . user_id ) \
2010-06-10 13:34:19 +00:00
WHERE l . id IN % s GROUP BY l . id ' ,(tuple(ids),))
2008-07-22 15:11:28 +00:00
res = dict ( cursor . fetchall ( ) )
sheet_names = { }
for sheet_id , name in sheet_obj . name_get ( cursor , user , res . values ( ) ,
context = context ) :
sheet_names [ sheet_id ] = name
for line_id in { } . fromkeys ( ids ) :
sheet_id = res . get ( line_id , False )
if sheet_id :
res [ line_id ] = ( sheet_id , sheet_names [ sheet_id ] )
else :
res [ line_id ] = False
return res
2010-05-11 07:15:29 +00:00
def _sheet_search ( self , cursor , user , obj , name , args , context = None ) :
2008-07-22 15:11:28 +00:00
if not len ( args ) :
return [ ]
sheet_obj = self . pool . get ( ' hr_timesheet_sheet.sheet ' )
i = 0
while i < len ( args ) :
fargs = args [ i ] [ 0 ] . split ( ' . ' , 1 )
if len ( fargs ) > 1 :
args [ i ] = ( fargs [ 0 ] , ' in ' , sheet_obj . search ( cursor , user ,
2010-07-27 07:11:45 +00:00
[ ( fargs [ 1 ] , args [ i ] [ 1 ] , args [ i ] [ 2 ] ) ] , context = context ) )
2008-07-22 15:11:28 +00:00
i + = 1
continue
if isinstance ( args [ i ] [ 2 ] , basestring ) :
res_ids = sheet_obj . name_search ( cursor , user , args [ i ] [ 2 ] , [ ] ,
args [ i ] [ 1 ] )
args [ i ] = ( args [ i ] [ 0 ] , ' in ' , [ x [ 0 ] for x in res_ids ] )
i + = 1
qu1 , qu2 = [ ] , [ ]
for x in args :
if x [ 1 ] != ' in ' :
if ( x [ 2 ] is False ) and ( x [ 1 ] == ' = ' ) :
qu1 . append ( ' (s.id IS NULL) ' )
elif ( x [ 2 ] is False ) and ( x [ 1 ] == ' <> ' or x [ 1 ] == ' != ' ) :
qu1 . append ( ' (s.id IS NOT NULL) ' )
else :
2009-05-01 09:56:06 +00:00
qu1 . append ( ' (s.id %s %s ) ' % ( x [ 1 ] , ' %s ' ) )
2008-07-22 15:11:28 +00:00
qu2 . append ( x [ 2 ] )
elif x [ 1 ] == ' in ' :
if len ( x [ 2 ] ) > 0 :
qu1 . append ( ' (s.id in ( %s )) ' % ( ' , ' . join ( [ ' %d ' ] * len ( x [ 2 ] ) ) ) )
qu2 + = x [ 2 ]
else :
qu1 . append ( ' (False) ' )
if len ( qu1 ) :
qu1 = ' WHERE ' + ' AND ' . join ( qu1 )
else :
qu1 = ' '
cursor . execute ( ' SELECT l.id \
FROM hr_timesheet_sheet_sheet s \
LEFT JOIN ( hr_analytic_timesheet l \
LEFT JOIN account_analytic_line al \
ON ( l . line_id = al . id ) ) \
ON ( s . date_to > = al . date \
AND s . date_from < = al . date \
AND s . user_id = al . user_id ) ' + \
qu1 , qu2 )
res = cursor . fetchall ( )
if not len ( res ) :
return [ ( ' id ' , ' = ' , ' 0 ' ) ]
return [ ( ' id ' , ' in ' , [ x [ 0 ] for x in res ] ) ]
_columns = {
2011-07-01 23:41:24 +00:00
' sheet_id ' : fields . function ( _sheet , string = ' Sheet ' ,
2008-07-22 15:11:28 +00:00
type = ' many2one ' , relation = ' hr_timesheet_sheet.sheet ' ,
fnct_search = _sheet_search ) ,
}
_defaults = {
' date ' : _get_default_date ,
}
2011-04-15 08:49:06 +00:00
def _check_sheet_state ( self , cr , uid , ids , context = None ) :
if context is None :
context = { }
2011-04-15 09:14:28 +00:00
for timesheet_line in self . browse ( cr , uid , ids , context = context ) :
if timesheet_line . sheet_id and timesheet_line . sheet_id . state not in ( ' draft ' , ' new ' ) :
2011-04-15 08:49:06 +00:00
return False
return True
_constraints = [
2011-04-15 09:14:28 +00:00
( _check_sheet_state , ' You can not modify an entry in a Confirmed/Done timesheet !. ' , [ ' state ' ] ) ,
2011-04-15 08:49:06 +00:00
]
2008-07-22 15:11:28 +00:00
def unlink ( self , cr , uid , ids , * args , * * kwargs ) :
2011-07-01 09:45:10 +00:00
if isinstance ( ids , ( int , long ) ) :
ids = [ ids ]
2008-07-22 15:11:28 +00:00
self . _check ( cr , uid , ids )
return super ( hr_timesheet_line , self ) . unlink ( 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 not in ( ' draft ' , ' new ' ) :
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You can not modify an entry in a confirmed timesheet ! ' ) )
return True
2007-08-30 14:22:22 +00:00
2007-03-05 18:22:32 +00:00
hr_timesheet_line ( )
class hr_attendance ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_inherit = " hr.attendance "
2010-07-27 07:11:45 +00:00
def _get_default_date ( self , cr , uid , context = None ) :
if context is None :
context = { }
2008-07-22 15:11:28 +00:00
if ' name ' in context :
return context [ ' name ' ] + time . strftime ( ' % H: % M: % S ' )
return time . strftime ( ' % Y- % m- %d % H: % M: % S ' )
2010-07-27 07:11:45 +00:00
def _sheet ( self , cursor , user , ids , name , args , context = None ) :
2008-07-22 15:11:28 +00:00
sheet_obj = self . pool . get ( ' hr_timesheet_sheet.sheet ' )
2009-03-31 09:44:33 +00:00
cursor . execute ( " SELECT a.id, COALESCE(MAX(s.id), 0) \
2008-07-22 15:11:28 +00:00
FROM hr_timesheet_sheet_sheet s \
LEFT JOIN ( hr_attendance a \
LEFT JOIN hr_employee e \
2010-01-29 06:40:57 +00:00
LEFT JOIN resource_resource r \
ON ( e . resource_id = r . id ) \
2008-07-22 15:11:28 +00:00
ON ( a . employee_id = e . id ) ) \
2009-11-26 13:54:00 +00:00
ON ( s . date_to > = date_trunc ( ' day ' , a . name ) \
AND s . date_from < = a . name \
2010-01-29 06:40:57 +00:00
AND s . user_id = r . user_id ) \
2010-06-10 13:34:19 +00:00
WHERE a . id IN % s GROUP BY a . id " ,(tuple(ids),))
2008-07-22 15:11:28 +00:00
res = dict ( cursor . fetchall ( ) )
sheet_names = { }
for sheet_id , name in sheet_obj . name_get ( cursor , user , res . values ( ) ,
context = context ) :
sheet_names [ sheet_id ] = name
for line_id in { } . fromkeys ( ids ) :
sheet_id = res . get ( line_id , False )
if sheet_id :
res [ line_id ] = ( sheet_id , sheet_names [ sheet_id ] )
else :
res [ line_id ] = False
return res
2010-05-11 07:15:29 +00:00
def _sheet_search ( self , cursor , user , obj , name , args , context = None ) :
2008-07-22 15:11:28 +00:00
if not len ( args ) :
return [ ]
2010-07-27 07:11:45 +00:00
sheet_obj = self . pool . get ( ' hr_timesheet_sheet.sheet ' )
2008-07-22 15:11:28 +00:00
i = 0
while i < len ( args ) :
fargs = args [ i ] [ 0 ] . split ( ' . ' , 1 )
if len ( fargs ) > 1 :
args [ i ] = ( fargs [ 0 ] , ' in ' , sheet_obj . search ( cursor , user ,
2010-07-27 07:11:45 +00:00
[ ( fargs [ 1 ] , args [ i ] [ 1 ] , args [ i ] [ 2 ] ) ] , context = context ) )
2008-07-22 15:11:28 +00:00
i + = 1
continue
if isinstance ( args [ i ] [ 2 ] , basestring ) :
res_ids = sheet_obj . name_search ( cursor , user , args [ i ] [ 2 ] , [ ] ,
args [ i ] [ 1 ] )
args [ i ] = ( args [ i ] [ 0 ] , ' in ' , [ x [ 0 ] for x in res_ids ] )
i + = 1
qu1 , qu2 = [ ] , [ ]
for x in args :
if x [ 1 ] != ' in ' :
if ( x [ 2 ] is False ) and ( x [ 1 ] == ' = ' ) :
qu1 . append ( ' (s.id IS NULL) ' )
elif ( x [ 2 ] is False ) and ( x [ 1 ] == ' <> ' or x [ 1 ] == ' != ' ) :
qu1 . append ( ' (s.id IS NOT NULL) ' )
else :
2009-05-01 09:56:06 +00:00
qu1 . append ( ' (s.id %s %s ) ' % ( x [ 1 ] , ' %s ' ) )
2008-07-22 15:11:28 +00:00
qu2 . append ( x [ 2 ] )
elif x [ 1 ] == ' in ' :
if len ( x [ 2 ] ) > 0 :
qu1 . append ( ' (s.id in ( %s )) ' % ( ' , ' . join ( [ ' %d ' ] * len ( x [ 2 ] ) ) ) )
qu2 + = x [ 2 ]
else :
qu1 . append ( ' (False) ' )
if len ( qu1 ) :
qu1 = ' WHERE ' + ' AND ' . join ( qu1 )
else :
qu1 = ' '
cursor . execute ( ' SELECT a.id \
FROM hr_timesheet_sheet_sheet s \
LEFT JOIN ( hr_attendance a \
LEFT JOIN hr_employee e \
ON ( a . employee_id = e . id ) ) \
2010-03-09 06:36:03 +00:00
LEFT JOIN resource_resource r \
ON ( e . resource_id = r . id ) \
2009-11-26 13:54:00 +00:00
ON ( s . date_to > = date_trunc ( \' day \' ,a.name) \
AND s . date_from < = a . name \
2010-03-09 06:36:03 +00:00
AND s . user_id = r . user_id ) ' + \
2008-07-22 15:11:28 +00:00
qu1 , qu2 )
res = cursor . fetchall ( )
if not len ( res ) :
return [ ( ' id ' , ' = ' , ' 0 ' ) ]
return [ ( ' id ' , ' in ' , [ x [ 0 ] for x in res ] ) ]
_columns = {
2011-07-01 23:41:24 +00:00
' sheet_id ' : fields . function ( _sheet , string = ' Sheet ' ,
2008-07-22 15:11:28 +00:00
type = ' many2one ' , relation = ' hr_timesheet_sheet.sheet ' ,
fnct_search = _sheet_search ) ,
}
_defaults = {
' name ' : _get_default_date ,
}
2010-07-21 12:39:48 +00:00
def create ( self , cr , uid , vals , context = None ) :
if context is None :
context = { }
2008-07-22 15:11:28 +00:00
if ' sheet_id ' in context :
2010-07-27 07:11:45 +00:00
ts = self . pool . get ( ' hr_timesheet_sheet.sheet ' ) . browse ( cr , uid , context [ ' sheet_id ' ] , context = context )
2008-07-22 15:11:28 +00:00
if ts . state not in ( ' draft ' , ' new ' ) :
2009-03-31 09:44:33 +00:00
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot modify an entry in a confirmed timesheet ! ' ) )
2008-07-22 15:11:28 +00:00
res = super ( hr_attendance , self ) . create ( cr , uid , vals , context = context )
if ' sheet_id ' in context :
2009-03-31 11:32:53 +00:00
if context [ ' sheet_id ' ] != self . browse ( cr , uid , res , context = context ) . sheet_id . id :
2009-03-31 09:44:33 +00:00
raise osv . except_osv ( _ ( ' UserError ' ) , _ ( ' You cannot enter an attendance ' \
2008-07-22 15:11:28 +00:00
' date outside the current timesheet dates! ' ) )
return res
def unlink ( self , cr , uid , ids , * args , * * kwargs ) :
2011-07-01 09:45:10 +00:00
if isinstance ( ids , ( int , long ) ) :
ids = [ ids ]
2008-07-22 15:11:28 +00:00
self . _check ( cr , uid , ids )
return super ( hr_attendance , self ) . unlink ( cr , uid , ids , * args , * * kwargs )
2010-07-27 07:11:45 +00:00
def write ( self , cr , uid , ids , vals , context = None ) :
2010-07-21 12:39:48 +00:00
if context is None :
context = { }
2011-07-01 09:45:10 +00:00
if isinstance ( ids , ( int , long ) ) :
ids = [ ids ]
2008-07-22 15:11:28 +00:00
self . _check ( cr , uid , ids )
res = super ( hr_attendance , self ) . write ( cr , uid , ids , vals , context = context )
if ' sheet_id ' in context :
for attendance in self . browse ( cr , uid , ids , context = context ) :
if context [ ' sheet_id ' ] != attendance . sheet_id . id :
2009-03-31 09:44:33 +00:00
raise osv . except_osv ( _ ( ' UserError ' ) , _ ( ' You cannot enter an attendance ' \
2008-07-22 15:11:28 +00:00
' date outside the current timesheet dates! ' ) )
return res
def _check ( self , cr , uid , ids ) :
for att in self . browse ( cr , uid , ids ) :
if att . sheet_id and att . sheet_id . state not in ( ' draft ' , ' new ' ) :
2009-03-31 09:44:33 +00:00
raise osv . except_osv ( _ ( ' Error ! ' ) , _ ( ' You cannot modify an entry in a confirmed timesheet ! ' ) )
2008-07-22 15:11:28 +00:00
return True
2007-08-30 14:22:22 +00:00
2007-03-05 18:22:32 +00:00
hr_attendance ( )
class hr_timesheet_sheet_sheet_day ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " hr_timesheet_sheet.sheet.day "
2010-05-19 18:32:32 +00:00
_description = " Timesheets by Period "
2008-07-22 15:11:28 +00:00
_auto = False
_order = ' name '
_columns = {
' name ' : fields . date ( ' Date ' , readonly = True ) ,
' sheet_id ' : fields . many2one ( ' hr_timesheet_sheet.sheet ' , ' Sheet ' , readonly = True , select = " 1 " ) ,
2011-01-06 05:35:21 +00:00
' total_timesheet ' : fields . float ( ' Total Timesheet ' , readonly = True ) ,
2008-07-22 15:11:28 +00:00
' total_attendance ' : fields . float ( ' Attendance ' , readonly = True ) ,
' total_difference ' : fields . float ( ' Difference ' , readonly = True ) ,
}
def init ( self , cr ) :
cr . execute ( """ create or replace view hr_timesheet_sheet_sheet_day as
SELECT
id ,
name ,
sheet_id ,
total_timesheet ,
total_attendance ,
2009-09-22 05:19:11 +00:00
cast ( round ( cast ( total_attendance - total_timesheet as Numeric ) , 2 ) as Double Precision ) AS total_difference
2008-07-22 15:11:28 +00:00
FROM
( (
SELECT
MAX ( id ) as id ,
name ,
sheet_id ,
SUM ( total_timesheet ) as total_timesheet ,
CASE WHEN SUM ( total_attendance ) < 0
THEN ( SUM ( total_attendance ) +
CASE WHEN current_date < > name
THEN 1440
ELSE ( EXTRACT ( hour FROM current_time ) * 60 ) + EXTRACT ( minute FROM current_time )
END
)
ELSE SUM ( total_attendance )
END / 60 as total_attendance
FROM
( (
select
min ( hrt . id ) as id ,
l . date : : date as name ,
s . id as sheet_id ,
sum ( l . unit_amount ) as total_timesheet ,
0.0 as total_attendance
from
hr_analytic_timesheet hrt
left join ( account_analytic_line l
LEFT JOIN hr_timesheet_sheet_sheet s
ON ( s . date_to > = l . date
AND s . date_from < = l . date
AND s . user_id = l . user_id ) )
on ( l . id = hrt . line_id )
group by l . date : : date , s . id
) union (
select
- min ( a . id ) as id ,
a . name : : date as name ,
s . id as sheet_id ,
0.0 as total_timesheet ,
SUM ( ( ( EXTRACT ( hour FROM a . name ) * 60 ) + EXTRACT ( minute FROM a . name ) ) * ( CASE WHEN a . action = ' sign_in ' THEN - 1 ELSE 1 END ) ) as total_attendance
from
hr_attendance a
LEFT JOIN ( hr_timesheet_sheet_sheet s
2010-01-19 07:35:47 +00:00
LEFT JOIN resource_resource r
LEFT JOIN hr_employee e
ON ( e . resource_id = r . id )
ON ( s . user_id = r . user_id ) )
2008-07-22 15:11:28 +00:00
ON ( a . employee_id = e . id
2009-11-26 13:54:00 +00:00
AND s . date_to > = date_trunc ( ' day ' , a . name )
AND s . date_from < = a . name )
2008-07-22 15:11:28 +00:00
WHERE action in ( ' sign_in ' , ' sign_out ' )
group by a . name : : date , s . id
) ) AS foo
GROUP BY name , sheet_id
) ) AS bar """ )
2007-08-30 14:22:22 +00:00
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 ) :
2008-07-22 15:11:28 +00:00
_name = " hr_timesheet_sheet.sheet.account "
2010-05-19 18:32:32 +00:00
_description = " Timesheets by Period "
2008-07-22 15:11:28 +00:00
_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 ) ,
' total ' : fields . float ( ' Total Time ' , digits = ( 16 , 2 ) , readonly = True ) ,
' invoice_rate ' : fields . many2one ( ' hr_timesheet_invoice.factor ' , ' Invoice rate ' , readonly = True ) ,
2008-12-11 11:50:52 +00:00
}
2008-07-22 15:11:28 +00:00
def init ( self , cr ) :
cr . execute ( """ create or replace view hr_timesheet_sheet_sheet_account as (
select
min ( hrt . id ) as id ,
l . account_id as name ,
s . id as sheet_id ,
sum ( l . unit_amount ) as total ,
l . to_invoice as invoice_rate
from
hr_analytic_timesheet hrt
left join ( account_analytic_line l
LEFT JOIN hr_timesheet_sheet_sheet s
ON ( s . date_to > = l . date
AND s . date_from < = l . date
AND s . user_id = l . user_id ) )
on ( l . id = hrt . line_id )
group by l . account_id , s . id , l . to_invoice
) """ )
2007-08-30 14:22:22 +00:00
2007-03-06 09:55:17 +00:00
hr_timesheet_sheet_sheet_account ( )
2007-08-30 14:22:22 +00:00
2008-09-07 23:24:39 +00:00
2007-03-06 09:55:17 +00:00
class res_company ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_inherit = ' res.company '
_columns = {
2008-09-07 23:24:39 +00:00
' timesheet_range ' : fields . selection (
2010-07-13 13:38:02 +00:00
[ ( ' day ' , ' Day ' ) , ( ' week ' , ' Week ' ) , ( ' month ' , ' Month ' ) , ( ' year ' , ' Year ' ) ] , ' Timesheet range ' ) ,
' timesheet_max_difference ' : fields . float ( ' Timesheet allowed difference(Hours) ' ,
help = " Allowed difference in hours between the sign in/out and the timesheet " \
2008-09-07 23:24:39 +00:00
" computation for one sheet. Set this to 0 if you do not want any control. " ) ,
2008-07-22 15:11:28 +00:00
}
_defaults = {
2010-09-16 05:59:56 +00:00
' timesheet_range ' : lambda * args : ' week ' ,
2008-07-22 15:11:28 +00:00
' timesheet_max_difference ' : lambda * args : 0.0
}
2007-08-30 14:22:22 +00:00
2007-03-06 09:55:17 +00:00
res_company ( )
2008-07-23 14:41:47 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: