2009-10-13 05:58:37 +00:00
# -*- coding: utf-8 -*-
2006-12-07 13:41:40 +00:00
##############################################################################
2010-01-12 05:32:48 +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>).
2006-12-07 13:41:40 +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.
2006-12-07 13:41:40 +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.
2006-12-07 13:41:40 +00:00
#
2009-10-14 11:15:34 +00:00
# You should have received a copy of the GNU Affero General Public License
2010-01-12 05:32:48 +00:00
# along with this program. If not, see <http://www.gnu.org/licenses/>.
2006-12-07 13:41:40 +00:00
#
##############################################################################
2010-08-12 04:17:18 +00:00
2012-03-30 08:26:50 +00:00
import logging
2013-04-16 15:18:44 +00:00
from openerp . modules . module import get_module_resource
2012-12-06 14:56:32 +00:00
from openerp . osv import fields , osv
2013-04-25 09:12:56 +00:00
from openerp . tools . translate import _
2012-12-06 14:56:32 +00:00
from openerp import tools
2013-03-20 11:15:20 +00:00
from openerp . tools . translate import _
2013-04-16 15:18:44 +00:00
2012-06-22 06:48:54 +00:00
_logger = logging . getLogger ( __name__ )
2010-10-25 10:05:42 +00:00
2013-04-17 07:27:50 +00:00
2006-12-07 13:41:40 +00:00
class hr_employee_category ( osv . osv ) :
2010-10-08 13:22:47 +00:00
def name_get ( self , cr , uid , ids , context = None ) :
2010-10-27 12:49:59 +00:00
if not ids :
2010-10-08 13:22:47 +00:00
return [ ]
2010-11-19 13:48:01 +00:00
reads = self . read ( cr , uid , ids , [ ' name ' , ' parent_id ' ] , context = context )
2010-10-08 13:22:47 +00:00
res = [ ]
for record in reads :
name = record [ ' name ' ]
if record [ ' parent_id ' ] :
name = record [ ' parent_id ' ] [ 1 ] + ' / ' + name
res . append ( ( record [ ' id ' ] , name ) )
return res
2010-11-19 13:48:01 +00:00
def _name_get_fnc ( self , cr , uid , ids , prop , unknow_none , context = None ) :
res = self . name_get ( cr , uid , ids , context = context )
2010-10-08 13:22:47 +00:00
return dict ( res )
2008-07-22 15:11:28 +00:00
_name = " hr.employee.category "
_description = " Employee Category "
_columns = {
2012-12-14 09:13:00 +00:00
' name ' : fields . char ( " Employee Tag " , size = 64 , required = True ) ,
2011-07-01 23:41:24 +00:00
' complete_name ' : fields . function ( _name_get_fnc , type = " char " , string = ' Name ' ) ,
2012-12-14 09:13:00 +00:00
' parent_id ' : fields . many2one ( ' hr.employee.category ' , ' Parent Employee Tag ' , select = True ) ,
2011-10-26 15:03:24 +00:00
' child_ids ' : fields . one2many ( ' hr.employee.category ' , ' parent_id ' , ' Child Categories ' ) ,
' employee_ids ' : fields . many2many ( ' hr.employee ' , ' employee_category_rel ' , ' category_id ' , ' emp_id ' , ' Employees ' ) ,
2008-07-22 15:11:28 +00:00
}
2010-01-12 05:32:48 +00:00
2010-07-07 07:04:42 +00:00
def _check_recursion ( self , cr , uid , ids , context = None ) :
2009-01-02 09:54:21 +00:00
level = 100
while len ( ids ) :
2010-07-03 10:21:52 +00:00
cr . execute ( ' select distinct parent_id from hr_employee_category where id IN %s ' , ( tuple ( ids ) , ) )
2009-01-02 09:54:21 +00:00
ids = filter ( None , map ( lambda x : x [ 0 ] , cr . fetchall ( ) ) )
if not level :
return False
level - = 1
return True
2010-01-12 05:32:48 +00:00
2009-01-02 09:54:21 +00:00
_constraints = [
2012-07-13 12:16:13 +00:00
( _check_recursion , ' Error! You cannot create recursive Categories. ' , [ ' parent_id ' ] )
2009-01-02 09:54:21 +00:00
]
2010-01-12 05:32:48 +00:00
2006-12-07 13:41:40 +00:00
2010-02-28 19:44:19 +00:00
class hr_job ( osv . osv ) :
2010-07-03 10:21:52 +00:00
def _no_of_employee ( self , cr , uid , ids , name , args , context = None ) :
2010-02-18 10:13:12 +00:00
res = { }
2010-11-19 13:48:01 +00:00
for job in self . browse ( cr , uid , ids , context = context ) :
2011-03-11 13:41:36 +00:00
nb_employees = len ( job . employee_ids or [ ] )
res [ job . id ] = {
' no_of_employee ' : nb_employees ,
' expected_employees ' : nb_employees + job . no_of_recruitment ,
}
2010-02-18 10:13:12 +00:00
return res
2011-11-24 10:12:09 +00:00
def _get_job_position ( self , cr , uid , ids , context = None ) :
2011-11-30 13:37:49 +00:00
res = [ ]
2011-11-25 08:33:52 +00:00
for employee in self . pool . get ( ' hr.employee ' ) . browse ( cr , uid , ids , context = context ) :
if employee . job_id :
2011-11-30 13:37:49 +00:00
res . append ( employee . job_id . id )
return res
2011-11-24 10:12:09 +00:00
2010-02-28 19:44:19 +00:00
_name = " hr.job "
2013-06-06 10:54:11 +00:00
_description = " Job Position "
2013-04-05 13:22:43 +00:00
_inherit = [ ' mail.thread ' , ' ir.needaction_mixin ' ]
2010-02-18 10:13:12 +00:00
_columns = {
2010-02-28 19:44:19 +00:00
' name ' : fields . char ( ' Job Name ' , size = 128 , required = True , select = True ) ,
2013-02-24 11:52:27 +00:00
# TO CLEAN: when doing a cleaning, we should change like this:
# no_of_recruitment: a function field
# expected_employees: float
# This would allow a clean update when creating new employees.
2012-11-03 13:47:30 +00:00
' expected_employees ' : fields . function ( _no_of_employee , string = ' Total Forecasted Employees ' ,
2012-06-13 13:18:34 +00:00
help = ' Expected number of employees for this job position after new recruitment. ' ,
2011-11-24 13:07:46 +00:00
store = {
2011-11-30 13:37:49 +00:00
' hr.job ' : ( lambda self , cr , uid , ids , c = None : ids , [ ' no_of_recruitment ' ] , 10 ) ,
2011-11-24 10:12:09 +00:00
' hr.employee ' : ( _get_job_position , [ ' job_id ' ] , 10 ) ,
2011-11-24 13:07:46 +00:00
} ,
2011-11-24 10:12:09 +00:00
multi = ' no_of_employee ' ) ,
2012-11-03 13:47:30 +00:00
' no_of_employee ' : fields . function ( _no_of_employee , string = " Current Number of Employees " ,
2012-06-13 13:18:34 +00:00
help = ' Number of employees currently occupying this job position. ' ,
2011-11-24 13:07:46 +00:00
store = {
2011-11-24 10:12:09 +00:00
' hr.employee ' : ( _get_job_position , [ ' job_id ' ] , 10 ) ,
2011-11-24 13:07:46 +00:00
} ,
2011-11-24 10:12:09 +00:00
multi = ' no_of_employee ' ) ,
2013-06-06 10:54:11 +00:00
' no_of_recruitment ' : fields . float ( ' Expected New Employees ' , help = ' Number of new employees you expect to recruit. ' ) ,
' no_of_hired_employee ' : fields . float ( ' Hired Employees ' , help = ' Number of hired employees for this job position during recruitment phase. ' ) ,
2012-06-04 12:44:17 +00:00
' employee_ids ' : fields . one2many ( ' hr.employee ' , ' job_id ' , ' Employees ' , groups = ' base.group_user ' ) ,
2010-02-18 10:13:12 +00:00
' description ' : fields . text ( ' Job Description ' ) ,
2010-07-03 10:21:52 +00:00
' requirements ' : fields . text ( ' Requirements ' ) ,
' department_id ' : fields . many2one ( ' hr.department ' , ' Department ' ) ,
2010-02-28 19:44:19 +00:00
' company_id ' : fields . many2one ( ' res.company ' , ' Company ' ) ,
2013-05-15 13:26:25 +00:00
' state ' : fields . selection ( [ ( ' open ' , ' No Recruitment ' ) , ( ' recruit ' , ' Recruitment in Progress ' ) ] , ' Status ' , readonly = True , required = True ,
2012-06-13 13:18:34 +00:00
help = " By default ' In position ' , set it to ' In Recruitment ' if recruitment process is going on for this job position. " ) ,
2013-04-03 10:42:29 +00:00
' color ' : fields . integer ( ' Color Index ' ) ,
2010-02-28 19:44:19 +00:00
}
2010-02-18 10:13:12 +00:00
_defaults = {
2010-02-28 19:44:19 +00:00
' company_id ' : lambda self , cr , uid , c : self . pool . get ( ' res.company ' ) . _company_default_get ( cr , uid , ' hr.job ' , context = c ) ,
2010-10-14 10:43:56 +00:00
' state ' : ' open ' ,
2010-02-28 19:44:19 +00:00
}
2011-11-24 10:12:09 +00:00
2011-08-05 05:20:25 +00:00
_sql_constraints = [
2012-12-14 13:26:56 +00:00
( ' name_company_uniq ' , ' unique(name, company_id, department_id) ' , ' The name of the job position must be unique per department in company! ' ) ,
2013-05-17 13:43:41 +00:00
( ' hired_employee_check ' , " CHECK ( no_of_hired_employee <= no_of_recruitment ) " , " Number of hired employee must be less than expected number of employee in recruitment. " ) ,
2011-08-05 05:20:25 +00:00
]
2010-04-13 05:21:13 +00:00
2011-03-11 13:41:36 +00:00
def on_change_expected_employee ( self , cr , uid , ids , no_of_recruitment , no_of_employee , context = None ) :
2010-10-14 10:43:56 +00:00
if context is None :
context = { }
2011-03-11 13:41:36 +00:00
return { ' value ' : { ' expected_employees ' : no_of_recruitment + no_of_employee } }
2010-10-14 10:43:56 +00:00
2013-06-19 09:32:03 +00:00
def action_employee_to_hire ( self , cr , uid , id , value , context = None ) :
return self . write ( cr , uid , [ id ] , { ' no_of_recruitment ' : value } , context = context )
2013-05-17 13:43:41 +00:00
2013-05-15 13:26:25 +00:00
def job_recruitment ( self , cr , uid , ids , * args ) :
2011-03-11 13:41:36 +00:00
for job in self . browse ( cr , uid , ids ) :
no_of_recruitment = job . no_of_recruitment == 0 and 1 or job . no_of_recruitment
2013-05-30 11:32:46 +00:00
self . write ( cr , uid , [ job . id ] , { ' state ' : ' recruit ' , ' no_of_recruitment ' : no_of_recruitment } )
2010-07-21 12:39:48 +00:00
return True
def job_open ( self , cr , uid , ids , * args ) :
2013-05-17 13:43:41 +00:00
self . write ( cr , uid , ids , { ' state ' : ' open ' , ' no_of_recruitment ' : 0 , ' no_of_hired_employee ' : 0 } )
2012-06-08 08:41:41 +00:00
return True
2013-06-20 05:49:09 +00:00
def write ( self , cr , uid , ids , vals , context = None ) :
if vals . get ( ' state ' ) == ' recruit ' :
2013-06-24 09:04:10 +00:00
self . message_post ( cr , uid , ids , body = _ ( ' job in <b>Recruitment</b> Stage ' ) , context = context )
2013-06-20 05:49:09 +00:00
return super ( hr_job , self ) . write ( cr , uid , ids , vals , context = context )
2010-02-18 10:13:12 +00:00
2006-12-07 13:41:40 +00:00
class hr_employee ( osv . osv ) :
2008-07-22 15:11:28 +00:00
_name = " hr.employee "
_description = " Employee "
2013-06-12 09:55:07 +00:00
_order = ' name_related '
2010-07-03 10:21:52 +00:00
_inherits = { ' resource.resource ' : " resource_id " }
2013-01-28 05:22:23 +00:00
_inherit = [ ' mail.thread ' ]
2012-02-21 13:12:28 +00:00
2013-07-23 14:45:07 +00:00
_mail_post_access = ' read '
2012-06-28 10:27:07 +00:00
def _get_image ( self , cr , uid , ids , name , args , context = None ) :
2012-03-23 10:04:39 +00:00
result = dict . fromkeys ( ids , False )
2012-06-28 10:27:07 +00:00
for obj in self . browse ( cr , uid , ids , context = context ) :
2012-08-07 11:10:39 +00:00
result [ obj . id ] = tools . image_get_resized_images ( obj . image )
2012-02-21 13:12:28 +00:00
return result
2013-06-12 09:55:07 +00:00
2012-06-28 10:27:07 +00:00
def _set_image ( self , cr , uid , id , name , value , args , context = None ) :
2012-08-07 11:10:39 +00:00
return self . write ( cr , uid , [ id ] , { ' image ' : tools . image_resize_image_big ( value ) } , context = context )
2013-06-12 09:55:07 +00:00
2008-07-22 15:11:28 +00:00
_columns = {
2012-11-13 15:03:37 +00:00
#we need a related field in order to be able to sort the employee by name
' name_related ' : fields . related ( ' resource_id ' , ' name ' , type = ' char ' , string = ' Name ' , readonly = True , store = True ) ,
2010-07-03 10:21:52 +00:00
' country_id ' : fields . many2one ( ' res.country ' , ' Nationality ' ) ,
2010-09-06 10:11:32 +00:00
' birthday ' : fields . date ( " Date of Birth " ) ,
2009-12-22 13:08:10 +00:00
' ssnid ' : fields . char ( ' SSN No ' , size = 32 , help = ' Social Security Number ' ) ,
2010-07-07 07:04:42 +00:00
' sinid ' : fields . char ( ' SIN No ' , size = 32 , help = " Social Insurance Number " ) ,
2010-09-11 13:29:00 +00:00
' identification_id ' : fields . char ( ' Identification No ' , size = 32 ) ,
2011-03-03 12:49:03 +00:00
' otherid ' : fields . char ( ' Other Id ' , size = 64 ) ,
2013-06-12 09:55:07 +00:00
' gender ' : fields . selection ( [ ( ' male ' , ' Male ' ) , ( ' female ' , ' Female ' ) ] , ' Gender ' ) ,
2011-04-08 16:31:16 +00:00
' marital ' : fields . selection ( [ ( ' single ' , ' Single ' ) , ( ' married ' , ' Married ' ) , ( ' widower ' , ' Widower ' ) , ( ' divorced ' , ' Divorced ' ) ] , ' Marital Status ' ) ,
2013-06-12 09:55:07 +00:00
' department_id ' : fields . many2one ( ' hr.department ' , ' Department ' ) ,
2012-03-07 05:21:00 +00:00
' address_id ' : fields . many2one ( ' res.partner ' , ' Working Address ' ) ,
' address_home_id ' : fields . many2one ( ' res.partner ' , ' Home Address ' ) ,
2013-06-12 09:55:07 +00:00
' bank_account_id ' : fields . many2one ( ' res.partner.bank ' , ' Bank Account Number ' , domain = " [( ' partner_id ' , ' = ' ,address_home_id)] " , help = " Employee bank salary account " ) ,
2010-12-07 09:21:23 +00:00
' work_phone ' : fields . char ( ' Work Phone ' , size = 32 , readonly = False ) ,
2011-02-16 11:23:43 +00:00
' mobile_phone ' : fields . char ( ' Work Mobile ' , size = 32 , readonly = False ) ,
2012-06-25 13:42:53 +00:00
' work_email ' : fields . char ( ' Work Email ' , size = 240 ) ,
2008-08-27 20:53:10 +00:00
' work_location ' : fields . char ( ' Office Location ' , size = 32 ) ,
2008-07-22 15:11:28 +00:00
' notes ' : fields . text ( ' Notes ' ) ,
2011-05-10 13:32:27 +00:00
' parent_id ' : fields . many2one ( ' hr.employee ' , ' Manager ' ) ,
2012-08-07 16:22:16 +00:00
' category_ids ' : fields . many2many ( ' hr.employee.category ' , ' employee_category_rel ' , ' emp_id ' , ' category_id ' , ' Tags ' ) ,
2010-07-03 10:21:52 +00:00
' child_ids ' : fields . one2many ( ' hr.employee ' , ' parent_id ' , ' Subordinates ' ) ,
2010-08-12 19:29:33 +00:00
' resource_id ' : fields . many2one ( ' resource.resource ' , ' Resource ' , ondelete = ' cascade ' , required = True ) ,
2010-07-21 12:39:48 +00:00
' coach_id ' : fields . many2one ( ' hr.employee ' , ' Coach ' ) ,
2010-05-21 13:05:52 +00:00
' job_id ' : fields . many2one ( ' hr.job ' , ' Job ' ) ,
2012-09-07 09:23:33 +00:00
# image: all image fields are base64 encoded and PIL-supported
2012-06-27 14:47:50 +00:00
' image ' : fields . binary ( " Photo " ,
2012-09-07 09:23:33 +00:00
help = " This field holds the image used as photo for the employee, limited to 1024x1024px. " ) ,
2012-06-28 10:27:07 +00:00
' image_medium ' : fields . function ( _get_image , fnct_inv = _set_image ,
string = " Medium-sized photo " , type = " binary " , multi = " _get_image " ,
2012-02-21 13:12:28 +00:00
store = {
2012-06-27 14:47:50 +00:00
' hr.employee ' : ( lambda self , cr , uid , ids , c = { } : ids , [ ' image ' ] , 10 ) ,
} ,
2012-06-28 10:27:07 +00:00
help = " Medium-sized photo of the employee. It is automatically " \
2012-09-07 09:51:55 +00:00
" resized as a 128x128px image, with aspect ratio preserved. " \
2012-06-27 14:47:50 +00:00
" Use this field in form views or some kanban views. " ) ,
2012-06-28 10:27:07 +00:00
' image_small ' : fields . function ( _get_image , fnct_inv = _set_image ,
string = " Smal-sized photo " , type = " binary " , multi = " _get_image " ,
2012-06-27 14:47:50 +00:00
store = {
' hr.employee ' : ( lambda self , cr , uid , ids , c = { } : ids , [ ' image ' ] , 10 ) ,
} ,
2012-06-28 10:27:07 +00:00
help = " Small-sized photo of the employee. It is automatically " \
2012-09-07 09:51:55 +00:00
" resized as a 64x64px image, with aspect ratio preserved. " \
2012-06-28 10:27:07 +00:00
" Use this field anywhere a small image is required. " ) ,
2013-06-12 09:55:07 +00:00
' passport_id ' : fields . char ( ' Passport No ' , size = 64 ) ,
2011-09-16 10:12:14 +00:00
' color ' : fields . integer ( ' Color Index ' ) ,
' city ' : fields . related ( ' address_id ' , ' city ' , type = ' char ' , string = ' City ' ) ,
2011-12-22 22:10:31 +00:00
' login ' : fields . related ( ' user_id ' , ' login ' , type = ' char ' , string = ' Login ' , readonly = 1 ) ,
2012-05-29 12:47:48 +00:00
' last_login ' : fields . related ( ' user_id ' , ' date ' , type = ' datetime ' , string = ' Latest Connection ' , readonly = 1 ) ,
2008-07-22 15:11:28 +00:00
}
2010-09-08 11:15:14 +00:00
2013-06-12 09:55:07 +00:00
def _get_default_image ( self , cr , uid , context = None ) :
image_path = get_module_resource ( ' hr ' , ' static/src/img ' , ' default_image.png ' )
return tools . image_resize_image_big ( open ( image_path , ' rb ' ) . read ( ) . encode ( ' base64 ' ) )
defaults = {
' active ' : 1 ,
' image ' : _get_default_image ,
' color ' : 0 ,
}
2012-11-13 15:03:37 +00:00
2012-07-20 13:29:52 +00:00
def create ( self , cr , uid , data , context = None ) :
2013-05-14 12:34:36 +00:00
if context is None :
context = { }
2013-05-10 14:48:29 +00:00
create_ctx = dict ( context , mail_create_nolog = True )
employee_id = super ( hr_employee , self ) . create ( cr , uid , data , context = create_ctx )
2013-04-17 09:49:27 +00:00
employee = self . browse ( cr , uid , employee_id , context = context )
2013-05-02 14:07:26 +00:00
if employee . user_id :
# send a copy to every user of the company
company_id = employee . user_id . partner_id . company_id . id
partner_ids = self . pool . get ( ' res.partner ' ) . search ( cr , uid , [
( ' company_id ' , ' = ' , company_id ) ,
( ' user_ids ' , ' != ' , False ) ] , context = context )
else :
partner_ids = [ ]
self . message_post ( cr , uid , [ employee_id ] ,
body = _ ( ' Welcome to %s ! Please help him/her take the first steps with OpenERP! ' ) % ( employee . name ) ,
partner_ids = partner_ids ,
subtype = ' mail.mt_comment ' , context = context
)
2012-07-20 13:29:52 +00:00
return employee_id
2011-04-26 11:27:55 +00:00
def unlink ( self , cr , uid , ids , context = None ) :
resource_ids = [ ]
for employee in self . browse ( cr , uid , ids , context = context ) :
2012-12-05 13:17:23 +00:00
resource_ids . append ( employee . resource_id . id )
return self . pool . get ( ' resource.resource ' ) . unlink ( cr , uid , resource_ids , context = context )
2011-04-26 11:27:55 +00:00
2010-12-07 09:21:23 +00:00
def onchange_address_id ( self , cr , uid , ids , address , context = None ) :
if address :
2012-03-07 05:21:00 +00:00
address = self . pool . get ( ' res.partner ' ) . browse ( cr , uid , address , context = context )
2012-10-04 06:43:47 +00:00
return { ' value ' : { ' work_phone ' : address . phone , ' mobile_phone ' : address . mobile } }
2010-12-07 09:21:23 +00:00
return { ' value ' : { } }
2010-10-27 12:49:59 +00:00
def onchange_company ( self , cr , uid , ids , company , context = None ) :
2010-10-21 12:20:20 +00:00
address_id = False
2010-10-27 12:49:59 +00:00
if company :
2010-11-19 13:48:01 +00:00
company_id = self . pool . get ( ' res.company ' ) . browse ( cr , uid , company , context = context )
2012-03-21 10:12:32 +00:00
address = self . pool . get ( ' res.partner ' ) . address_get ( cr , uid , [ company_id . partner_id . id ] , [ ' default ' ] )
2010-10-21 12:20:20 +00:00
address_id = address and address [ ' default ' ] or False
2013-06-12 09:55:07 +00:00
return { ' value ' : { ' address_id ' : address_id } }
2010-09-08 11:15:14 +00:00
2011-03-11 10:54:49 +00:00
def onchange_department_id ( self , cr , uid , ids , department_id , context = None ) :
value = { ' parent_id ' : False }
if department_id :
department = self . pool . get ( ' hr.department ' ) . browse ( cr , uid , department_id )
value [ ' parent_id ' ] = department . manager_id . id
return { ' value ' : value }
2010-09-08 11:15:14 +00:00
def onchange_user ( self , cr , uid , ids , user_id , context = None ) :
2010-10-21 12:20:20 +00:00
work_email = False
if user_id :
2012-08-10 14:43:39 +00:00
work_email = self . pool . get ( ' res.users ' ) . browse ( cr , uid , user_id , context = context ) . email
2013-06-12 09:55:07 +00:00
return { ' value ' : { ' work_email ' : work_email } }
2010-10-08 13:22:47 +00:00
2013-03-20 11:15:20 +00:00
def action_follow ( self , cr , uid , ids , context = None ) :
""" Wrapper because message_subscribe_users take a user_ids=None
that receive the context without the wrapper . """
return self . message_subscribe_users ( cr , uid , ids , context = context )
def action_unfollow ( self , cr , uid , ids , context = None ) :
""" Wrapper because message_unsubscribe_users take a user_ids=None
that receive the context without the wrapper . """
return self . message_unsubscribe_users ( cr , uid , ids , context = context )
2013-04-03 15:24:43 +00:00
def get_suggested_thread ( self , cr , uid , removed_suggested_threads = None , context = None ) :
""" Show the suggestion of employees if display_employees_suggestions if the
user perference allows it . """
user = self . pool . get ( ' res.users ' ) . browse ( cr , uid , uid , context )
if not user . display_employees_suggestions :
return [ ]
else :
return super ( hr_employee , self ) . get_suggested_thread ( cr , uid , removed_suggested_threads , context )
2013-04-17 08:40:26 +00:00
def _message_get_auto_subscribe_fields ( self , cr , uid , updated_fields , auto_follow_fields = [ ' user_id ' ] , context = None ) :
""" Overwrite of the original method to always follow user_id field,
even when not track_visibility so that a user will follow it ' s employee
"""
user_field_lst = [ ]
for name , column_info in self . _all_columns . items ( ) :
if name in auto_follow_fields and name in updated_fields and column_info . column . _obj == ' res.users ' :
user_field_lst . append ( name )
return user_field_lst
2010-01-12 05:32:48 +00:00
2010-07-07 07:04:42 +00:00
def _check_recursion ( self , cr , uid , ids , context = None ) :
2009-01-02 09:54:21 +00:00
level = 100
while len ( ids ) :
2010-08-12 06:02:33 +00:00
cr . execute ( ' SELECT DISTINCT parent_id FROM hr_employee WHERE id IN %s AND parent_id!=id ' , ( tuple ( ids ) , ) )
2009-01-02 09:54:21 +00:00
ids = filter ( None , map ( lambda x : x [ 0 ] , cr . fetchall ( ) ) )
if not level :
return False
level - = 1
return True
2010-01-12 05:32:48 +00:00
2009-01-02 09:54:21 +00:00
_constraints = [
2012-07-13 12:16:13 +00:00
( _check_recursion , ' Error! You cannot create recursive hierarchy of Employee(s). ' , [ ' parent_id ' ] ) ,
2009-01-02 09:54:21 +00:00
]
2006-12-07 13:41:40 +00:00
2010-02-18 10:13:12 +00:00
2010-07-21 12:39:48 +00:00
class hr_department ( osv . osv ) :
_description = " Department "
_inherit = ' hr.department '
_columns = {
' manager_id ' : fields . many2one ( ' hr.employee ' , ' Manager ' ) ,
2010-12-21 10:00:28 +00:00
' member_ids ' : fields . one2many ( ' hr.employee ' , ' department_id ' , ' Members ' , readonly = True ) ,
2010-07-21 12:39:48 +00:00
}
2012-08-27 13:16:19 +00:00
def copy ( self , cr , uid , ids , default = None , context = None ) :
2012-04-25 07:24:09 +00:00
if default is None :
default = { }
default = default . copy ( )
2012-09-10 17:02:02 +00:00
default [ ' member_ids ' ] = [ ]
return super ( hr_department , self ) . copy ( cr , uid , ids , default , context = context )
2011-03-10 13:18:27 +00:00
class res_users ( osv . osv ) :
_name = ' res.users '
_inherit = ' res.users '
def create ( self , cr , uid , data , context = None ) :
user_id = super ( res_users , self ) . create ( cr , uid , data , context = context )
2011-11-24 10:12:09 +00:00
2011-06-24 08:50:18 +00:00
# add shortcut unless 'noshortcut' is True in context
if not ( context and context . get ( ' noshortcut ' , False ) ) :
data_obj = self . pool . get ( ' ir.model.data ' )
try :
data_id = data_obj . _get_id ( cr , uid , ' hr ' , ' ir_ui_view_sc_employee ' )
view_id = data_obj . browse ( cr , uid , data_id , context = context ) . res_id
self . pool . get ( ' ir.ui.view_sc ' ) . copy ( cr , uid , view_id , default = {
' user_id ' : user_id } , context = context )
except :
# Tolerate a missing shortcut. See product/product.py for similar code.
2012-07-25 12:13:54 +00:00
_logger . debug ( ' Skipped meetings shortcut for user " %s " . ' , data . get ( ' name ' , ' <new ' ) )
2011-11-24 10:12:09 +00:00
2011-03-10 13:18:27 +00:00
return user_id
2012-07-10 13:32:55 +00:00
_columns = {
' employee_ids ' : fields . one2many ( ' hr.employee ' , ' user_id ' , ' Related employees ' ) ,
}
2011-03-10 13:18:27 +00:00
2010-09-06 10:11:32 +00:00
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: