2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2008-09-18 15:42:10 +00:00
##############################################################################
2009-11-26 11:59:07 +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>).
2008-09-18 15:42:10 +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.
2008-09-18 15:42:10 +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.
2008-09-18 15:42:10 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2009-11-26 11:59:07 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2008-09-18 15:42:10 +00:00
#
##############################################################################
2008-09-16 14:29:24 +00:00
import time
from osv import fields , osv
from tools . translate import _
class hr_action_reason ( osv . osv ) :
_name = " hr.action.reason "
2010-05-19 18:32:32 +00:00
_description = " Action Reason "
2008-09-16 14:29:24 +00:00
_columns = {
2010-07-03 10:21:52 +00:00
' name ' : fields . char ( ' Reason ' , size = 64 , required = True , help = ' Specifies the reason for Signing In/Signing Out. ' ) ,
' action_type ' : fields . selection ( [ ( ' sign_in ' , ' Sign in ' ) , ( ' sign_out ' , ' Sign out ' ) ] , " Action ' s type " ) ,
2008-09-16 14:29:24 +00:00
}
_defaults = {
2010-07-03 10:21:52 +00:00
' action_type ' : ' sign_in ' ,
2008-09-16 14:29:24 +00:00
}
hr_action_reason ( )
2010-04-13 05:37:36 +00:00
def _employee_get ( obj , cr , uid , context = None ) :
2010-07-03 10:21:52 +00:00
ids = obj . pool . get ( ' hr.employee ' ) . search ( cr , uid , [ ( ' user_id ' , ' = ' , uid ) ] )
2008-09-16 14:29:24 +00:00
if ids :
return ids [ 0 ]
return False
class hr_attendance ( osv . osv ) :
_name = " hr.attendance "
_description = " Attendance "
2010-03-18 17:39:33 +00:00
def _day_compute ( self , cr , uid , ids , fieldnames , args , context = None ) :
res = dict . fromkeys ( ids , ' ' )
for obj in self . browse ( cr , uid , ids , context = context ) :
res [ obj . id ] = time . strftime ( ' % Y- % m- %d ' , time . strptime ( obj . name , ' % Y- % m- %d % H: % M: % S ' ) )
return res
2010-07-03 10:21:52 +00:00
2008-09-16 14:29:24 +00:00
_columns = {
2010-07-03 10:21:52 +00:00
' name ' : fields . datetime ( ' Date ' , required = True , select = 1 ) ,
' action ' : fields . selection ( [ ( ' sign_in ' , ' Sign In ' ) , ( ' sign_out ' , ' Sign Out ' ) , ( ' action ' , ' Action ' ) ] , ' Action ' , required = True ) ,
' action_desc ' : fields . many2one ( " hr.action.reason " , " Action reason " , domain = " [( ' action_type ' , ' = ' , action)] " , help = ' Specifies the reason for Signing In/Signing Out in case of extra hours. ' ) ,
' employee_id ' : fields . many2one ( ' hr.employee ' , " Employee ' s Name " , required = True , select = True ) ,
' day ' : fields . function ( _day_compute , method = True , type = ' char ' , string = ' Day ' , store = True , select = 1 , size = 32 ) ,
2008-09-16 14:29:24 +00:00
}
_defaults = {
2010-07-03 10:21:52 +00:00
' name ' : time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) ,
' employee_id ' : _employee_get ,
2008-09-16 14:29:24 +00:00
}
2009-11-26 11:59:07 +00:00
2008-09-16 14:29:24 +00:00
def _altern_si_so ( self , cr , uid , ids ) :
for id in ids :
sql = '''
select action , name
from hr_attendance as att
where employee_id = ( select employee_id from hr_attendance where id = % s )
and action in ( ' sign_in ' , ' sign_out ' )
and name < = ( select name from hr_attendance where id = % s )
order by name desc
2009-11-26 11:59:07 +00:00
limit 2 '''
cr . execute ( sql , ( id , id ) )
2008-09-16 14:29:24 +00:00
atts = cr . fetchall ( )
if not ( ( len ( atts ) == 1 and atts [ 0 ] [ 0 ] == ' sign_in ' ) or ( atts [ 0 ] [ 0 ] != atts [ 1 ] [ 0 ] and atts [ 0 ] [ 1 ] != atts [ 1 ] [ 1 ] ) ) :
return False
return True
2009-11-26 11:59:07 +00:00
2008-09-16 14:29:24 +00:00
_constraints = [ ( _altern_si_so , ' Error: Sign in (resp. Sign out) must follow Sign out (resp. Sign in) ' , [ ' action ' ] ) ]
_order = ' name desc '
hr_attendance ( )
class hr_employee ( osv . osv ) :
_inherit = " hr.employee "
_description = " Employee "
2009-11-26 11:59:07 +00:00
2010-04-13 05:37:36 +00:00
def _state ( self , cr , uid , ids , name , args , context = None ) :
2008-09-16 14:29:24 +00:00
result = { }
for id in ids :
result [ id ] = ' absent '
cr . execute ( ' SELECT hr_attendance.action, hr_attendance.employee_id \
FROM ( \
SELECT MAX ( name ) AS name , employee_id \
FROM hr_attendance \
WHERE action in ( \' sign_in \' , \' sign_out \' ) \
GROUP BY employee_id \
) AS foo \
LEFT JOIN hr_attendance \
ON ( hr_attendance . employee_id = foo . employee_id \
AND hr_attendance . name = foo . name ) \
2010-06-10 13:34:19 +00:00
WHERE hr_attendance . employee_id IN % s ' ,(tuple(ids),))
2008-09-16 14:29:24 +00:00
for res in cr . fetchall ( ) :
result [ res [ 1 ] ] = res [ 0 ] == ' sign_in ' and ' present ' or ' absent '
return result
2009-11-26 11:59:07 +00:00
2008-09-16 14:29:24 +00:00
_columns = {
' state ' : fields . function ( _state , method = True , type = ' selection ' , selection = [ ( ' absent ' , ' Absent ' ) , ( ' present ' , ' Present ' ) ] , string = ' Attendance ' ) ,
}
2009-11-26 11:59:07 +00:00
2010-07-03 10:21:52 +00:00
def _action_check ( self , cr , uid , emp_id , dt = False , context = None ) :
2008-12-10 14:29:55 +00:00
cr . execute ( ' select max(name) from hr_attendance where employee_id= %s ' , ( emp_id , ) )
2008-09-16 14:29:24 +00:00
res = cr . fetchone ( )
return not ( res and ( res [ 0 ] > = ( dt or time . strftime ( ' % Y- % m- %d % H: % M: % S ' ) ) ) )
2010-07-03 10:21:52 +00:00
def attendance_action_change ( self , cr , uid , ids , type = ' action ' , context = None , dt = False , * args ) :
2008-09-16 14:29:24 +00:00
id = False
2009-12-21 11:03:05 +00:00
warning_sign = ' sign '
2010-01-18 15:14:10 +00:00
#Special case when button calls this method :type=context
2010-07-03 10:21:52 +00:00
if isinstance ( type , dict ) :
2010-01-18 15:14:10 +00:00
type = type . get ( ' type ' , ' action ' )
2009-12-21 11:03:05 +00:00
if type == ' sign_in ' :
warning_sign = " Sign In "
elif type == ' sign_out ' :
2010-04-13 05:37:36 +00:00
warning_sign = " Sign Out "
2009-12-21 11:03:05 +00:00
for emp in self . read ( cr , uid , ids , [ ' id ' ] , context = context ) :
if not self . _action_check ( cr , uid , emp [ ' id ' ] , dt , context ) :
raise osv . except_osv ( _ ( ' Warning ' ) , _ ( ' You tried to %s with a date anterior to another event ! \n Try to contact the administrator to correct attendances. ' ) % ( warning_sign , ) )
2010-04-13 05:37:36 +00:00
2010-07-03 10:21:52 +00:00
res = { ' action ' : type , ' employee_id ' : emp [ ' id ' ] }
2010-01-18 15:14:10 +00:00
2008-09-16 14:29:24 +00:00
if dt :
res [ ' name ' ] = dt
id = self . pool . get ( ' hr.attendance ' ) . create ( cr , uid , res , context = context )
2010-04-13 05:37:36 +00:00
2009-12-21 11:03:05 +00:00
if type != ' action ' :
return id
2010-07-03 10:21:52 +00:00
2009-12-21 11:03:05 +00:00
return True
2010-04-13 05:37:36 +00:00
2008-09-16 14:29:24 +00:00
hr_employee ( )
2009-11-26 11:59:07 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: