[IMP] hr related modules improvements
[odoo/odoo.git] / addons / hr / hr.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Management Solution
5 #    Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21 import os
22
23 from osv import fields, osv
24 import tools
25 from tools.translate import _
26
27 class hr_employee_category(osv.osv):
28     _name = "hr.employee.category"
29     _description = "Employee Category"
30     _columns = {
31         'name': fields.char("Category", size=64, required=True),
32         'parent_id': fields.many2one('hr.employee.category', 'Parent Category', select=True),
33         'child_ids': fields.one2many('hr.employee.category', 'parent_id', 'Child Categories')
34     }
35
36     def _check_recursion(self, cr, uid, ids, context=None):
37         if context is None:
38             context = {}
39         level = 100
40         while len(ids):
41             cr.execute('select distinct parent_id from hr_employee_category where id IN %s', (tuple(ids), ))
42             ids = filter(None, map(lambda x:x[0], cr.fetchall()))
43             if not level:
44                 return False
45             level -= 1
46         return True
47
48     _constraints = [
49         (_check_recursion, 'Error ! You cannot create recursive Categories.', ['parent_id'])
50     ]
51
52 hr_employee_category()
53
54 class hr_employee_marital_status(osv.osv):
55     _name = "hr.employee.marital.status"
56     _description = "Employee Marital Status"
57     _columns = {
58         'name': fields.char('Marital Status', size=32, required=True),
59         'description': fields.text('Status Description'),
60     }
61
62 hr_employee_marital_status()
63
64 class hr_job(osv.osv):
65
66     def _no_of_employee(self, cr, uid, ids, name, args, context=None):
67         if context is None:
68             context = {}
69         res = {}
70         for emp in self.browse(cr, uid, ids):
71             res[emp.id] = len(emp.employee_ids or [])
72         return res
73
74     _name = "hr.job"
75     _description = "Job Description"
76     _columns = {
77         'name': fields.char('Job Name', size=128, required=True, select=True),
78         'expected_employees': fields.integer('Expected Employees', help='Required number of Employees'),
79         'no_of_employee': fields.function(_no_of_employee, method=True, string='No of Employees', type='integer', help='Number of Employees selected'),
80         'employee_ids': fields.one2many('hr.employee', 'job_id', 'Employees'),
81         'description': fields.text('Job Description'),
82         'requirements': fields.text('Requirements'),
83         'department_id': fields.many2one('hr.department', 'Department'),
84         'company_id': fields.many2one('res.company', 'Company'),
85         'state': fields.selection([('open', 'Open'),('old', 'Old'),('recruit', 'In Recruitement')], 'State', readonly=True, required=True),
86     }
87     _defaults = {
88         'expected_employees': 1,
89         'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'hr.job', context=c),
90         'state': 'open'
91     }
92
93     def job_old(self, cr, uid, ids, *args):
94         self.write(cr, uid, ids, {'state': 'old'})
95         return True
96
97     def job_recruitement(self, cr, uid, ids, *args):
98         self.write(cr, uid, ids, {'state': 'recruit'})
99         return True
100
101     def job_open(self, cr, uid, ids, *args):
102         self.write(cr, uid, ids, {'state': 'open'})
103         return True
104
105 hr_job()
106
107 class hr_employee(osv.osv):
108     _name = "hr.employee"
109     _description = "Employee"
110     _inherits = {'resource.resource': "resource_id"}
111     _columns = {
112         'country_id': fields.many2one('res.country', 'Nationality'),
113         'birthday': fields.date("Birthday"),
114         'ssnid': fields.char('SSN No', size=32, help='Social Security Number'),
115         'sinid': fields.char('SIN No', size=32, help="Social Insurance Number"),
116         'otherid': fields.char('Other ID', size=32),
117         'gender': fields.selection([('male', 'Male'),('female', 'Female')], 'Gender'),
118         'marital': fields.many2one('hr.employee.marital.status', 'Marital Status'),
119         'bank_account': fields.char('Bank Account', size=64),
120         'partner_id': fields.related('company_id', 'partner_id', type='many2one', relation='res.partner', readonly=True),
121         'department_id':fields.many2one('hr.department', 'Department'),
122         'address_id': fields.many2one('res.partner.address', 'Working Address'),
123         'address_home_id': fields.many2one('res.partner.address', 'Home Address'),
124         'work_phone': fields.related('address_id', 'phone', type='char', string='Work Phone', readonly=True),
125         'work_email': fields.related('address_id', 'email', type='char', size=240, string='Work E-mail', readonly=True),
126         'work_location': fields.char('Office Location', size=32),
127         'notes': fields.text('Notes'),
128         'parent_id': fields.many2one('hr.employee', 'Manager', select=True),
129 #        'parent_id': fields.related('department_id', 'manager_id',  string='Manager', type='many2one'),
130 #        'category_id': fields.many2one('hr.employee.category', 'Category'),
131         'category_ids': fields.many2many('hr.employee.category', 'employee_category_rel','category_id','emp_id','Category'),
132         'child_ids': fields.one2many('hr.employee', 'parent_id', 'Subordinates'),
133         'resource_id': fields.many2one('resource.resource', 'Resource', ondelete='cascade'),
134         'coach_id': fields.many2one('hr.employee', 'Coach'),
135         'job_id': fields.many2one('hr.job', 'Job'),
136         'photo': fields.binary('Photo')
137     }
138
139     def _get_photo(self, cr, uid, context=None):
140         if context is None:
141             context = {}
142         return open(os.path.join(
143             tools.config['addons_path'], 'hr/image', 'photo.png'),
144                     'rb') .read().encode('base64')
145
146     _defaults = {
147         'active': 1,
148         'photo': _get_photo,
149     }
150
151     def _check_recursion(self, cr, uid, ids, context=None):
152         if context is None:
153             context = {}
154         level = 100
155         while len(ids):
156             cr.execute('select distinct parent_id from hr_employee where id IN %s',(tuple(ids),))
157             ids = filter(None, map(lambda x:x[0], cr.fetchall()))
158             if not level:
159                 return False
160             level -= 1
161         return True
162
163     _constraints = [
164         (_check_recursion, 'Error ! You cannot create recursive Hierarchy of Employees.', ['parent_id'])
165     ]
166
167 hr_employee()
168
169 class hr_department(osv.osv):
170     _description = "Department"
171     _inherit = 'hr.department'
172     _columns = {
173         'manager_id': fields.many2one('hr.employee', 'Manager'),
174 #        'member_ids': fields.many2many('hr.employee', 'hr_department_user_rel', 'department_id', 'user_id', 'Members'),
175         'member_ids': fields.one2many('hr.employee', 'department_id', 'Members'),
176 #       finding problem to implement one2many field as "hr_departmen_user_rel" is used in another module query
177     }
178
179 hr_department()
180
181
182 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: