diff options
| author | Vir (Open ERP) <vir@tinyerp.com> | 2010-01-20 12:26:11 +0530 |
|---|---|---|
| committer | Vir (Open ERP) <vir@tinyerp.com> | 2010-01-20 12:26:11 +0530 |
| commit | ed6420b082a4e5e2fc0dae0aafbfaf0af5d34c07 (patch) | |
| tree | bd62c36d2627d0500619f506e8c395434c21cc02 /addons/resource | |
| parent | 2a5ccc7f7fc2fb8dc963a49fa46ecfbd82824908 (diff) | |
| parent | d351065fb195ed7d20a5087a0f650fc37672f39e (diff) | |
Merge with trunk addons
bzr revid: vir@tinyerp.com-20100120065611-inrbplhiwq2p5tg5
Diffstat (limited to 'addons/resource')
| -rwxr-xr-x | addons/resource/__init__.py | 26 | ||||
| -rwxr-xr-x | addons/resource/__terp__.py | 49 | ||||
| -rwxr-xr-x | addons/resource/hr_demo.xml | 90 | ||||
| -rwxr-xr-x | addons/resource/hr_department.py | 153 | ||||
| -rwxr-xr-x | addons/resource/hr_department_demo.xml | 63 | ||||
| -rwxr-xr-x | addons/resource/hr_department_view.xml | 79 | ||||
| -rwxr-xr-x | addons/resource/hr_view.xml | 296 | ||||
| -rwxr-xr-x | addons/resource/resource.py | 191 | ||||
| -rwxr-xr-x | addons/resource/resource_view.xml | 174 | ||||
| -rw-r--r-- | addons/resource/security/ir.model.access.csv | 5 |
10 files changed, 1126 insertions, 0 deletions
diff --git a/addons/resource/__init__.py b/addons/resource/__init__.py new file mode 100755 index 00000000000..2aa86a90c65 --- /dev/null +++ b/addons/resource/__init__.py @@ -0,0 +1,26 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# 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. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +import resource + + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: + diff --git a/addons/resource/__terp__.py b/addons/resource/__terp__.py new file mode 100755 index 00000000000..4970fe2ceac --- /dev/null +++ b/addons/resource/__terp__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# 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. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + + +{ + "name" : "Resource", + "version" : "1.1", + "author" : "Tiny", + "category" : "Generic Modules/Projects", + "website" : "http://www.openerp.com", + "description": """ + Module for resource management. You can manage: + * Leave/Holidays or Days off of the company + + """, + 'author': 'Tiny', + 'website': 'http://www.openerp.com', + 'depends': ['base', 'process'], + 'init_xml': [], + 'update_xml': [ + #'security/resource_security.xml', +# 'security/ir.model.access.csv', + 'resource_view.xml', + ], + 'demo_xml': [#'resource_demo.xml' + ], + 'installable': True, + 'active': False, + 'certificate': None, +} +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/resource/hr_demo.xml b/addons/resource/hr_demo.xml new file mode 100755 index 00000000000..fc01109d86c --- /dev/null +++ b/addons/resource/hr_demo.xml @@ -0,0 +1,90 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + + <!-- Example employee --> + + <record id="timesheet_group1" model="resource.calendar"> + <field name="name">38 Hours/Week</field> + </record> + + <record id="employee1" model="hr.employee"> + <field name="name">Fabien Pinckaers</field> + <!--<field name="regime">45</field>--> + <field name="user_id" ref="base.user_root"/> + <!--<field name="holiday_max">25</field>--> + </record> + + <record model="resource.calendar.week"> + <field name="name">Monday morning</field> + <field name="dayofweek">0</field> + <field name="hour_from">08</field> + <field name="hour_to">12</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Monday evening</field> + <field name="dayofweek">0</field> + <field name="hour_from">13</field> + <field name="hour_to">18</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Tuesday morning</field> + <field name="dayofweek">1</field> + <field name="hour_from">08</field> + <field name="hour_to">12</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Tuesday evening</field> + <field name="dayofweek">1</field> + <field name="hour_from">13</field> + <field name="hour_to">18</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Wednesday morning</field> + <field name="dayofweek">2</field> + <field name="hour_from">08</field> + <field name="hour_to">12</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Wednesday evening</field> + <field name="dayofweek">2</field> + <field name="hour_from">13</field> + <field name="hour_to">18</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Thursday morning</field> + <field name="dayofweek">3</field> + <field name="hour_from">08</field> + <field name="hour_to">12</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Thursday evening</field> + <field name="hour_from">13</field> + <field name="hour_to">18</field> + <field name="dayofweek">3</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Friday morning</field> + <field name="dayofweek">4</field> + <field name="hour_from">08</field> + <field name="hour_to">12</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + <record model="resource.calendar.week"> + <field name="name">Friday evening</field> + <field name="dayofweek">4</field> + <field name="hour_from">13</field> + <field name="hour_to">18</field> + <field name="calendar_id" ref="timesheet_group1"/> + </record> + + </data> +</openerp> diff --git a/addons/resource/hr_department.py b/addons/resource/hr_department.py new file mode 100755 index 00000000000..907bc55a435 --- /dev/null +++ b/addons/resource/hr_department.py @@ -0,0 +1,153 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# 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. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## + +from osv import fields,osv +import tools + +class hr_department(osv.osv): + _name = "hr.department" + _columns = { + 'name': fields.char('Department Name', size=64, required=True), + 'company_id': fields.many2one('res.company', 'Company', select=True, required=True), + 'parent_id': fields.many2one('hr.department', 'Parent Department', select=True), + 'child_ids': fields.one2many('hr.department', 'parent_id', 'Child Departments'), + 'note': fields.text('Note'), + 'manager_id': fields.many2one('res.users', 'Manager', required=True), + 'member_ids': fields.many2many('res.users', 'hr_department_user_rel', 'department_id', 'user_id', 'Members'), + } + def _get_members(self,cr, uid, context={}): + mids = self.search(cr, uid, [('manager_id','=',uid)]) + result = {uid:1} + for m in self.browse(cr, uid, mids, context): + for user in m.member_ids: + result[user.id] = 1 + return result.keys() + def _check_recursion(self, cr, uid, ids): + level = 100 + while len(ids): + cr.execute('select distinct parent_id from hr_department where id in ('+','.join(map(str, ids))+')') + ids = filter(None, map(lambda x:x[0], cr.fetchall())) + if not level: + return False + level -= 1 + return True + + _constraints = [ + (_check_recursion, 'Error! You can not create recursive departments.', ['parent_id']) + ] + +hr_department() + + +class ir_action_window(osv.osv): + _inherit = 'ir.actions.act_window' + + def read(self, cr, uid, ids, fields=None, context=None, + load='_classic_read'): + select = ids + if isinstance(ids, (int, long)): + select = [ids] + res = super(ir_action_window, self).read(cr, uid, select, fields=fields, + context=context, load=load) + for r in res: + mystring = 'department_users_get()' + if mystring in (r.get('domain', '[]') or ''): + r['domain'] = r['domain'].replace(mystring, str( + self.pool.get('hr.department')._get_members(cr, uid))) + if isinstance(ids, (int, long)): + if res: + return res[0] + else: + return False + return res + +ir_action_window() + +class res_users(osv.osv): + _inherit = 'res.users' + _description = 'res.users' + + def _parent_compute(self, cr, uid, ids, name, args, context={}): + result = {} + obj_dept = self.pool.get('hr.department') + for user_id in ids: + ids_dept = obj_dept.search(cr, uid, [('member_ids', 'in', [user_id])]) + parent_ids = [] + if ids_dept: + data_dept = obj_dept.read(cr, uid, ids_dept, ['manager_id']) + parent_ids = map(lambda x: x['manager_id'][0], data_dept) + result[user_id] = parent_ids + return result + + def _parent_search(self, cr, uid, obj, name, args): + parent = [] + for arg in args: + if arg[0] == 'parent_id': + parent = arg[2] + child_ids = self._child_compute(cr, uid, parent,name, args, {}) + if not child_ids: + return [('id', 'in', [0])] + return [('id', 'in', child_ids.get(uid,[]))] + + def _child_compute(self, cr, uid, ids, name, args, context={}): + obj_dept = self.pool.get('hr.department') + obj_user = self.pool.get('res.users') + result = {} + for manager_id in ids: + child_ids = [] + mgnt_dept_ids = obj_dept.search(cr, uid, [('manager_id', '=', manager_id)]) + ids_dept = obj_dept.search(cr, uid, [('id', 'child_of', mgnt_dept_ids)]) + if ids_dept: + data_dept = obj_dept.read(cr, uid, ids_dept, ['member_ids']) + childs = map(lambda x: x['member_ids'], data_dept) + childs = tools.flatten(childs) + childs = obj_user.search(cr, uid, [('id','in',childs),('active','=',True)]) + if manager_id in childs: + childs.remove(manager_id) + + child_ids.extend(tools.flatten(childs)) + set = {} + map(set.__setitem__, child_ids, []) + child_ids = set.keys() + else: + child_ids = [] + result[manager_id] = child_ids + return result + + def _child_search(self, cr, uid, obj, name, args): + parent = [] + for arg in args: + if arg[0] == 'child_ids': + parent = arg[2] + child_ids = self._child_compute(cr, uid, parent,name, args, {}) + if not child_ids: + return [('id', 'in', [0])] + return [('id', 'in', child_ids.get(uid,[]))] + + _columns = { + 'parent_id': fields.function(_parent_compute, relation='res.users',fnct_search=_parent_search, method=True, string="Managers", type='many2many'), + 'child_ids': fields.function(_child_compute, relation='res.users', fnct_search=_child_search,method=True, string="Subordinates", type='many2many'), + } + + +res_users() + +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
\ No newline at end of file diff --git a/addons/resource/hr_department_demo.xml b/addons/resource/hr_department_demo.xml new file mode 100755 index 00000000000..c7ea68f1dc3 --- /dev/null +++ b/addons/resource/hr_department_demo.xml @@ -0,0 +1,63 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data noupdate="1"> + + <record id="dep_management" model="hr.department"> + <field name="name">Management</field> + <field name="company_id" ref="base.main_company"/> + <field name="manager_id" ref="base.user_root"/> + </record> + <record id="dep_administration" model="hr.department"> + <field name="name">Administration</field> + <field name="parent_id" ref="dep_management"/> + <field name="company_id" ref="base.main_company"/> + <field name="manager_id" ref="base.user_root"/> + </record> + + <record id="dep_technical" model="hr.department"> + <field name="name">Technical department</field> + <field name="parent_id" ref="dep_management"/> + <field name="company_id" ref="base.main_company"/> + <field name="manager_id" ref="base.user_root"/> + </record> + + <record id="dep_it" model="hr.department"> + <field name="name">IT</field> + <field name="parent_id" ref="dep_technical"/> + <field name="company_id" ref="base.main_company"/> + <field name="manager_id" ref="base.user_root"/> + </record> + + <record id="dep_marketing" model="hr.department"> + <field name="name">Marketing</field> + <field name="parent_id" ref="dep_management"/> + <field name="company_id" ref="base.main_company"/> + <field name="manager_id" ref="base.user_root"/> + </record> + + <record id="dep_sales" model="hr.department"> + <field name="name">Sales</field> + <field name="company_id" ref="base.main_company"/> + <field name="manager_id" ref="base.user_root"/> + <field name="parent_id" ref="dep_management"/> + </record> + + <record id="dep_sales_europe" model="hr.department"> + <field name="name">Sales Europe</field> + <field name="company_id" ref="base.main_company"/> + <field name="manager_id" ref="base.user_root"/> + <field name="parent_id" ref="dep_sales"/> + </record> + + <record id="dep_sales_america" model="hr.department"> + <field name="name">Sales America</field> + <field name="company_id" ref="base.main_company"/> + <field name="manager_id" ref="base.user_root"/> + <field name="parent_id" ref="dep_sales"/> + </record> + + + + + </data> +</openerp> diff --git a/addons/resource/hr_department_view.xml b/addons/resource/hr_department_view.xml new file mode 100755 index 00000000000..fe65d988237 --- /dev/null +++ b/addons/resource/hr_department_view.xml @@ -0,0 +1,79 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + + <!-- + ====================== + department + ====================== + --> + <record id="view_department_form" model="ir.ui.view"> + <field name="name">hr.department.form</field> + <field name="model">hr.department</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="department"> + <field colspan="4" name="name" select="1"/> + <field name="company_id" select="1" widget="selection" groups="base.group_multi_company"/> + <field name="parent_id" select="2"/> + <field colspan="4" name="manager_id" select="1"/> + <notebook colspan="4" > + <page string="Members"> + <field colspan="4" name="member_ids" nolabel="1"/> + </page> + <page string="Notes"> + <field colspan="4" name="note" nolabel="1"/> + </page> + </notebook> + </form> + </field> + </record> + <record id="view_department_tree" model="ir.ui.view"> + <field name="name">hr.department.tree</field> + <field name="model">hr.department</field> + <field name="type">tree</field> + <field name="field_parent">child_ids</field> + <field name="arch" type="xml"> + <tree string="Companies"> + <field name="name"/> + <field name="company_id" groups="base.group_multi_company"/> + <field name="manager_id"/> + </tree> + </field> + </record> + <record id="open_module_tree_department_tree" model="ir.actions.act_window"> + <field name="name">Departments</field> + <field name="res_model">hr.department</field> + <field name="view_type">tree</field> + <field name="domain">[('parent_id','=',False)]</field> + </record> + <menuitem action="open_module_tree_department_tree" id="menu_department_tree" parent="base.menu_users"/> + + <record id="open_module_tree_department" model="ir.actions.act_window"> + <field name="name">Departments</field> + <field name="res_model">hr.department</field> + <field name="view_type">form</field> + </record> + + <menuitem action="open_module_tree_department" id="menu_department_def" parent="hr.menu_department_tree"/> + + <!-- res.users inherit --> + <record model="ir.ui.view" id="view_users_form_inherit"> + <field name="name">res.users.form</field> + <field name="type">form</field> + <field name="model">res.users</field> + <field name="inherit_id" ref="base.view_users_form"/> + <field name="arch" type="xml"> + <notebook position="inside"> + <page string="Departements Informations"> + <separator string="Managers" colspan="4"/> + <field name="parent_id" nolabel="1" colspan="4"/> + <separator string="Subordinates" colspan="4"/> + <field name="child_ids" nolabel="1" colspan="4"/> + </page> + </notebook> + </field> + </record> + + </data> +</openerp> diff --git a/addons/resource/hr_view.xml b/addons/resource/hr_view.xml new file mode 100755 index 00000000000..abf3c5f023f --- /dev/null +++ b/addons/resource/hr_view.xml @@ -0,0 +1,296 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + <menuitem icon="terp-hr" id="menu_hr_root" name="Human Resources"/> + <menuitem + id="menu_hr_reporting" + name="Reporting" + parent="hr.menu_hr_root" + sequence="40" /> + <menuitem + id="menu_hr_configuration" + name="Configuration" + parent="hr.menu_hr_root" + sequence="5" groups="group_hr_manager"/> + + <!-- + ========== + Employee + ========== + --> + <record id="view_employee_form" model="ir.ui.view"> + <field name="name">hr.employee.form</field> + <field name="model">hr.employee</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Employee"> + <group colspan="4" col="4"> + <field name="name" select="1"/> + <field name="active" select="1"/> + <field name="company_id" widget="selection" groups="base.group_multi_company"/> + <field name="user_id"/> + </group> + <notebook colspan="4"> + <page string="Personal Information"> + <group col="2" colspan="2"> + <separator colspan="2" string="Social IDs"/> + <field name="ssnid"/> + <field name="sinid"/> + <field name="otherid"/> + </group> + <group col="2" colspan="2"> + <separator string="Status" colspan="2"/> + <field name="gender"/> + <field name="marital"/> + <field name="country_id"/> + <field name="birthday"/> + </group> + + <group col="2" colspan="2"> + <separator string="Contact Information" colspan="2"/> + <field name="address_home_id" colspan="2"/> + <field name="address_id" colspan="2"/> + <field name="work_phone"/> + <field name="work_email" widget="email" /> + <field name="work_location"/> + </group> + + <group col="4" colspan="2"> + <separator string="Job Information" colspan="4"/> + <field name="parent_id" select="1" colspan="4"/> + + <field name="category_id" colspan="4" widget="selection"/> + </group> + </page> + <page string="Notes"> + <field colspan="4" nolabel="1" name="notes"/> + </page> + </notebook> + </form> + </field> + </record> + + <record id="view_employee_tree" model="ir.ui.view"> + <field name="name">hr.employee.tree</field> + <field name="model">hr.employee</field> + <field name="type">tree</field> + <field name="field_parent">child_ids</field> + <field name="arch" type="xml"> + <tree string="Employees"> + <field name="name"/> + <field name="work_phone"/> + <field name="work_email"/> + <field name="address_id"/> + <field name="parent_id"/> + </tree> + </field> + </record> + <record id="open_view_employee_tree" model="ir.actions.act_window"> + <field name="name">Employees Structure</field> + <field name="res_model">hr.employee</field> + <field name="view_type">tree</field> + <field name="view_mode">tree,form</field> + <field name="view_id" ref="view_employee_tree"/> + <field name="domain">[('parent_id','=',False)]</field> + </record> + + <record id="open_view_employee_list" model="ir.actions.act_window"> + <field name="name">Employees</field> + <field name="res_model">hr.employee</field> + <field name="view_type">form</field> + <field name="view_mode">tree,form</field> + <field name="view_id" eval="False"/> + </record> + <menuitem + id="menu_open_view_employee_list" + name="Employees" + groups="group_hr_manager" + parent="hr.menu_hr_root"/> + + <menuitem + action="open_view_employee_tree" + id="menu_open_view_employee_tree" + parent="menu_open_view_employee_list"/> + + <record id="open_view_employee_list_my" model="ir.actions.act_window"> + <field name="name">All Employees</field> + <field name="res_model">hr.employee</field> + <field name="view_type">form</field> + <field name="view_mode">tree,form</field> + <field name="domain">[]</field> + </record> + <menuitem + action="open_view_employee_list_my" + id="menu_open_view_employee_list_my" + parent="menu_open_view_employee_list"/> + + <!-- + ======================= + Employee architecture + ======================= + --> + <record id="view_partner_tree2" model="ir.ui.view"> + <field name="name">hr.employee.tree</field> + <field name="model">hr.employee</field> + <field name="type">tree</field> + <field name="field_parent">child_ids</field> + <field name="arch" type="xml"> + <tree string="Employees"> + <field name="name"/> + <field name="user_id"/> + <field name="address_id"/> + + </tree> + </field> + </record> + <record id="action2" model="ir.actions.act_window"> + <field name="name">Employee Hierarchy</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">hr.employee</field> + <field name="domain">[('id','in',active_ids)]</field> + <field name="view_type">tree</field> + <field name="view_id" ref="view_partner_tree2"/> + </record> + <ir_set> + <field eval="'action'" name="key"/> + <field eval="'client_action_multi'" name="key2"/> + <field eval="['hr.employee']" name="models"/> + <field name="name">Employees Hierarchy</field> + <field eval="'ir.actions.act_window,'+str(action2)" name="value"/> + <field eval="True" name="isobject"/> + <field eval="True" name="replace"/> + </ir_set> + + + <!-- + ============ + Working Time + ============ + --> + <record id="create_group" model="ir.ui.view"> + <field name="name">resource.calendar.form</field> + <field name="model">resource.calendar</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Working Time Category"> + <field name="name" select="1"/> + <field name="manager" select="1"/> + <newline/> + <field colspan="4" name="week_id" nolabel="1" widget="one2many_list"/> + </form> + </field> + </record> + <record id="edit_workgroup" model="ir.actions.act_window"> + <field name="name">Working Time Categories</field> + <field name="res_model">resource.calendar</field> + <field name="view_type">form</field> + <field name="view_id" eval="False"/> + </record> + <menuitem action="edit_workgroup" id="menu_edit_workgroup" parent="hr.menu_hr_configuration"/> + + <record id="view_timesheet_tree" model="ir.ui.view"> + <field name="name">resource.calendar.week.tree</field> + <field name="model">resource.calendar.week</field> + <field name="type">tree</field> + <field name="arch" type="xml"> + <tree string="Working Time"> + <field name="name"/> + <field name="dayofweek"/> + <field name="hour_from" widget="float_time"/> + <field name="hour_to" widget="float_time"/> + </tree> + </field> + </record> + <record id="view_timesheet_form" model="ir.ui.view"> + <field name="name">resource.calendar.week.form</field> + <field name="model">resource.calendar.week</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Working Time"> + <field colspan="4" name="name" select="1"/> + <field name="date_from"/> + <field name="dayofweek" select="1"/> + <field name="hour_from" widget="float_time"/> + <field name="hour_to" widget="float_time"/> + </form> + </field> + </record> + + <!-- + ============ + Employee Category + ============ + --> + + <record id="view_employee_category_form" model="ir.ui.view"> + <field name="name">hr.employee.category.form</field> + <field name="model">hr.employee.category</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Employee Category"> + <field name="name" select="1"/> + <field name="parent_id" select="1"/> + </form> + </field> + </record> + <record id="view_employee_category_list" model="ir.ui.view"> + <field name="name">hr.employee.category.list</field> + <field name="model">hr.employee.category</field> + <field name="type">tree</field> + <field eval="8" name="priority"/> + <field name="arch" type="xml"> + <tree string="Employees Categories"> + <field name="name"/> + <field name="parent_id"/> + </tree> + </field> + </record> + <record id="view_employee_category_tree" model="ir.ui.view"> + <field name="name">hr.employee.category.tree</field> + <field name="model">hr.employee.category</field> + <field name="type">tree</field> + <field name="field_parent">child_ids</field> + <field name="arch" type="xml"> + <tree string="Employees Categories"> + <field name="name"/> + </tree> + </field> + </record> + <record id="open_view_categ_form" model="ir.actions.act_window"> + <field name="name">Categories of Employee</field> + <field name="res_model">hr.employee.category</field> + <field name="view_type">form</field> + <field name="view_mode">tree,form</field> + </record> + <menuitem action="open_view_categ_form" id="menu_view_employee_category_form" parent="hr.menu_hr_configuration"/> + + <record id="open_view_categ_tree" model="ir.actions.act_window"> + <field name="name">Categories structure</field> + <field name="res_model">hr.employee.category</field> + <field name="view_type">tree</field> + <field name="view_id" ref="view_employee_category_tree"/> + <field name="domain">[('parent_id','=',False)]</field> + </record> + + <record id="hr_employee_normal_action_tree" model="ir.actions.act_window"> + <field name="name">Employees</field> + <field name="type">ir.actions.act_window</field> + <field name="res_model">hr.employee</field> + <field name="view_type">form</field> + <field name="view_mode">tree,form</field> + <field name="domain">[('category_id','child_of',[active_id])]</field> + <field name="context">{'category_id':active_id}</field> + </record> + + <record id="hr_employee_category_open" model="ir.values"> + <field eval="'tree_but_open'" name="key2"/> + <field eval="'hr.employee.category'" name="model"/> + <field name="name">Employees by Categories</field> + <field eval="'ir.actions.act_window,%d'%hr_employee_normal_action_tree" name="value"/> + <field eval="True" name="object"/> + </record> + + <menuitem action="open_view_categ_tree" id="menu_view_employee_category_tree" parent="hr.menu_view_employee_category_form"/> + + </data> +</openerp> diff --git a/addons/resource/resource.py b/addons/resource/resource.py new file mode 100755 index 00000000000..7ac36e5e7bd --- /dev/null +++ b/addons/resource/resource.py @@ -0,0 +1,191 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>). +# +# This program is free software: you can redistribute it and/or modify +# 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. +# +# 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 Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. +# +############################################################################## +import mx.DateTime +import time +import math +from osv import fields, osv +from tools.translate import _ + +class resource_calendar(osv.osv): + _name = "resource.calendar" + _description = "Resource Calendar" + _columns = { + 'name' : fields.char("Name", size=64, required=True), + 'company_id' : fields.many2one('res.company', 'Company', required=True), + 'week_id' : fields.one2many('resource.calendar.week', 'calendar_id', 'Working Time'), + 'manager' : fields.many2one('res.users', 'Workgroup manager'), + } + _defaults = { + 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.calendar', c) + } + def interval_min_get(self, cr, uid, id, dt_from, hours , resource=0): + dt_leave = [] + if not id: + return [(dt_from-mx.DateTime.RelativeDateTime(hours=int(hours)*3), dt_from)] + if resource: + resource_leave_ids = self.pool.get('resource.calendar.leaves').search(cr,uid,[('resource_id','=',resource)]) + if resource_leave_ids: + res_leaves = self.pool.get('resource.calendar.leaves').read(cr,uid,resource_leave_ids,['date_from','date_to']) + for i in range(len(res_leaves)): + dtf = mx.DateTime.strptime(res_leaves[i]['date_from'],'%Y-%m-%d %H:%M:%S') + dtt = mx.DateTime.strptime(res_leaves[i]['date_to'],'%Y-%m-%d %H:%M:%S') + leave_days = ((dtt - dtf).days) + 1 + for x in range(int(leave_days)): + dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d')) + dt_leave.sort() + todo = hours + cycle = 0 + result = [] + maxrecur = 100 + current_hour = dt_from.hour + while (todo>0) and maxrecur: + cr.execute("select hour_from,hour_to from resource_calendar_week where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.day_of_week,id)) + for (hour_from,hour_to) in cr.fetchall(): + if (hour_to>current_hour) and (todo>0): + m = max(hour_from, current_hour) + if (hour_to-m)>todo: + hour_to = m+todo + d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60)) + d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60)) + dt1 = d1.strftime('%Y-%m-%d') + dt2 = d2.strftime('%Y-%m-%d') + for i in range(len(dt_leave)): + if dt1 == dt_leave[i]: + dt_from += mx.DateTime.RelativeDateTime(days=1) + d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60)) + d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60)) + dt1 = d1.strftime('%Y-%m-%d') + dt2 = d2.strftime('%Y-%m-%d') + result.append((d1, d2)) + current_hour = hour_to + todo -= (hour_to - m) + dt_from += mx.DateTime.RelativeDateTime(days=1) + current_hour = 0 + maxrecur -= 1 + return result + + def interval_get(self, cr, uid, id, dt_from, hours, resource=0, byday=True): + dt_leave = [] + if not id: + return [(dt_from,dt_from+mx.DateTime.RelativeDateTime(hours=int(hours)*3))] + if resource: + resource_leave_ids = self.pool.get('resource.calendar.leaves').search(cr,uid,[('resource_id','=',resource)]) + if resource_leave_ids: + res_leaves = self.pool.get('resource.calendar.leaves').read(cr,uid,resource_leave_ids,['date_from','date_to']) + for i in range(len(res_leaves)): + dtf = mx.DateTime.strptime(res_leaves[i]['date_from'],'%Y-%m-%d %H:%M:%S') + dtt = mx.DateTime.strptime(res_leaves[i]['date_to'],'%Y-%m-%d %H:%M:%S') + no = dtt - dtf + leave_days = no.days + 1 + for x in range(int(leave_days)): + dt_leave.append((dtf + mx.DateTime.RelativeDateTime(days=x)).strftime('%Y-%m-%d')) + dt_leave.sort() + todo = hours + cycle = 0 + result = [] + maxrecur = 100 + current_hour = dt_from.hour + while (todo>0) and maxrecur: + cr.execute("select hour_from,hour_to from resource_calendar_week where dayofweek='%s' and calendar_id=%s order by hour_from", (dt_from.day_of_week,id)) + for (hour_from,hour_to) in cr.fetchall(): + if (hour_to>current_hour) and (todo>0): + m = max(hour_from, current_hour) + if (hour_to-m)>todo: + hour_to = m+todo + d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60)) + d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60)) + dt1 = d1.strftime('%Y-%m-%d') + dt2 = d2.strftime('%Y-%m-%d') + for i in range(len(dt_leave)): + if dt1 == dt_leave[i]: + dt_from += mx.DateTime.RelativeDateTime(days=1) + d1 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(m)),int((m%1) * 60)) + d2 = mx.DateTime.DateTime(dt_from.year,dt_from.month,dt_from.day,int(math.floor(hour_to)),int((hour_to%1) * 60)) + dt1 = d1.strftime('%Y-%m-%d') + dt2 = d2.strftime('%Y-%m-%d') + result.append((d1, d2)) + current_hour = hour_to + todo -= (hour_to - m) + dt_from += mx.DateTime.RelativeDateTime(days=1) + current_hour = 0 + maxrecur -= 1 + return result + +resource_calendar() + +class resource_calendar_week(osv.osv): + _name = "resource.calendar.week" + _description = "Work Detail" + _columns = { + 'name' : fields.char("Name", size=64, required=True), + 'dayofweek': fields.selection([('0','Monday'),('1','Tuesday'),('2','Wednesday'),('3','Thursday'),('4','Friday'),('5','Saturday'),('6','Sunday')], 'Day of week'), + 'date_from' : fields.date('Starting date'), + 'hour_from' : fields.float('Work from', size=8, required=True), + 'hour_to' : fields.float("Work to", size=8, required=True), + 'calendar_id' : fields.many2one("resource.calendar", "Resource's Calendar", required=True), + } + _order = 'dayofweek, hour_from' +resource_calendar_week() + +class resource_resource(osv.osv): + _name = "resource.resource" + _description = "Resource Detail" + _columns = { + 'name' : fields.char("Name", size=64, required=True ), + 'code': fields.char('Code', size=16), + 'active' : fields.boolean('Active', help="If the active field is set to true, it will allow you to hide the resource record without removing it."), + 'company_id' : fields.many2one('res.company', 'Company', required=True), + 'resource_type': fields.selection([('user','Human'),('material','Material')], 'Resource Type', required=True), + 'user_id' : fields.many2one('res.users', 'User',help='Related user name for the resource to manage its access.'), + 'time_efficiency' : fields.float('Efficiency factor', size=8, help="This field depict the efficiency of the resource to complete tasks. e.g resource put alone on a phase of 5 days with 5 tasks assigned to him, will show a load of 100% for this phase by default, but if we put a efficency of 200%, then his load will only be 50%."), + 'calendar_id' : fields.many2one("resource.calendar", "Working time", help="Define the schedule of resource"), + } + _defaults = { + 'resource_type' : lambda *a: 'user', + 'time_efficiency' : lambda *a: 1, + 'active' : lambda *a: True, + 'company_id': lambda self,cr,uid,c: self.pool.get('res.company')._company_default_get(cr, uid, 'resource.resource', c) + } +resource_resource() + +class resource_calendar_leaves(osv.osv): + _name = "resource.calendar.leaves" + _description = "Leave Detail" + _columns = { + 'name' : fields.char("Name", size=64), + 'company_id' : fields.related('calendar_id','company_id',type='many2one',relation='res.company',string="Company",readonly=True), + 'calendar_id' : fields.many2one("resource.calendar", "Working time"), + 'date_from' : fields.datetime('Start Date', required=True), + 'date_to' : fields.datetime('End Date', required=True), + 'resource_id' : fields.many2one("resource.resource", "Resource", help="If empty, this is a generic holiday for the company. If a resource is set, the holiday/leave is only for this resource"), + } + def check_dates(self, cr, uid, ids): + leave = self.read(cr, uid, ids[0],['date_from','date_to']) + if leave['date_from'] and leave['date_to']: + if leave['date_from'] > leave['date_to']: + return False + return True + + _constraints = [ + (check_dates, 'Error! leave start-date must be lower then leave end-date.', ['date_from', 'date_to']) + ] +resource_calendar_leaves() +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/resource/resource_view.xml b/addons/resource/resource_view.xml new file mode 100755 index 00000000000..80d0650e0c8 --- /dev/null +++ b/addons/resource/resource_view.xml @@ -0,0 +1,174 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + <menuitem icon="terp-hr" id="menu_resource_root" name="Resources Management"/> + <menuitem + id="menu_resource_reporting" + name="Reporting" + parent="menu_resource_root" + sequence="40" /> + <menuitem + id="menu_resource_configuration" + name="Configuration" + parent="menu_resource_root" + sequence="5"/> + + + <record id="resource_calendar_form" model="ir.ui.view"> + <field name="name">resource.calendar.form</field> + <field name="model">resource.calendar</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Resource Calendar"> + <field name="name" select="1"/> + <field name="manager" select="1"/> + <field name="company_id" select="1"/> + <newline/> + <field colspan="4" name="week_id" nolabel="1" widget="one2many_list"/> + </form> + </field> + </record> + <record id="action_resource_calendar_form" model="ir.actions.act_window"> + <field name="name">Resource Calendar</field> + <field name="res_model">resource.calendar</field> + <field name="view_type">form</field> + <field name="view_id" eval="False"/> + </record> + <menuitem string="Resource Calendar" action="action_resource_calendar_form" id="menu_resource_calendar_form" parent="menu_resource_configuration"/> + + <record id="view_resource_calendar_week_tree" model="ir.ui.view"> + <field name="name">resource.calendar.week.tree</field> + <field name="model">resource.calendar.week</field> + <field name="type">tree</field> + <field name="arch" type="xml"> + <tree string="Working Time"> + <field name="name"/> + <field name="dayofweek"/> + <field name="hour_from" widget="float_time"/> + <field name="hour_to" widget="float_time"/> + </tree> + </field> + </record> + <record id="view_resource_calendar_week_form" model="ir.ui.view"> + <field name="name">resource.calendar.week.form</field> + <field name="model">resource.calendar.week</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Working Time"> + <field colspan="4" name="name" select="1"/> + <field name="date_from"/> + <field name="dayofweek" select="1"/> + <field name="hour_from" widget="float_time"/> + <field name="hour_to" widget="float_time"/> + </form> + </field> + </record> + + <record id="view_resource_calendar" model="ir.ui.view"> + <field name="name">resource.calendar.leaves.calendar</field> + <field name="model">resource.calendar.leaves</field> + <field name="type">calendar</field> + <field name="arch" type="xml"> + <calendar color="resource_id" date_start="date_from" string="Resource"> + <field name="name"/> + + </calendar> + </field> + </record> + + + <act_window + id="resource_calendar_closing_days" + name="Closing Days" + res_model="resource.calendar.leaves" + src_model="resource.calendar" + view_mode="calendar,tree,form" + domain="[('calendar_id','=',active_id), ('resource_id','=',False)]"/> + + <act_window + id="resource_calendar_resources_leaves" + name="Resources Leaves" + res_model="resource.calendar.leaves" + src_model="resource.calendar" + view_mode="calendar,tree,form" + domain="[('calendar_id','=',active_id), ('resource_id','!=',False)]"/> + + + <record id="resource_resource_form" model="ir.ui.view"> + <field name="name">resource.resource.form</field> + <field name="model">resource.resource</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Resource"> + <field name="name" /> + <field name="active"/> + <field name="company_id" /> + <field name="calendar_id" /> + <field name="resource_type" /> + <field name="user_id" attrs="{'required':[('resource_type','=','user')]}"/> + <field name="time_efficiency" /> + </form> + </field> + </record> + <record id="resource_resource_tree" model="ir.ui.view"> + <field name="name">resource.resource.tree</field> + <field name="model">resource.resource</field> + <field name="type">tree</field> + <field name="arch" type="xml"> + <tree string="Resource"> + <field name="name" /> + <field name="company_id" /> + <field name="calendar_id" /> + <field name="resource_type" /> + <field name="user_id" /> + <field name="time_efficiency" /> + </tree> + </field> + </record> + <record id="action_resource_resource_tree" model="ir.actions.act_window"> + <field name="name">Resources</field> + <field name="res_model">resource.resource</field> + <field name="view_mode">tree,form</field> + </record> + <menuitem action="action_resource_resource_tree" id="menu_resource_resource_tree" parent="menu_resource_root"/> + + <record id="resource_calendar_leave_form" model="ir.ui.view"> + <field name="name">resource.calendar.leaves.form</field> + <field name="model">resource.calendar.leaves</field> + <field name="type">form</field> + <field name="arch" type="xml"> + <form string="Leave Detail"> + <field name="name" /> + <field name="company_id" /> + <field name="calendar_id" /> + <field name="date_from" /> + <field name="date_to" /> + <field name="resource_id" /> + </form> + </field> + </record> + <record id="resource_calendar_leave_tree" model="ir.ui.view"> + <field name="name">resource.calendar.leaves.tree</field> + <field name="model">resource.calendar.leaves</field> + <field name="type">tree</field> + <field name="arch" type="xml"> + <tree string="Leave Detail"> + <field name="name" /> + <field name="company_id" /> + <field name="calendar_id" /> + <field name="date_from" /> + <field name="date_to" /> + <field name="resource_id" /> + </tree> + </field> + </record> + <record id="action_resource_calendar_leave_tree" model="ir.actions.act_window"> + <field name="name">Leaves</field> + <field name="res_model">resource.calendar.leaves</field> + <field name="view_mode">tree,form,calendar</field> + </record> + <menuitem action="action_resource_calendar_leave_tree" id="menu_resource_calendar_leave_tree" parent="menu_resource_root"/> + + + </data> +</openerp> diff --git a/addons/resource/security/ir.model.access.csv b/addons/resource/security/ir.model.access.csv new file mode 100644 index 00000000000..0874bf97235 --- /dev/null +++ b/addons/resource/security/ir.model.access.csv @@ -0,0 +1,5 @@ +"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" +"access_hr_timesheet_group","resource.calendar","model_resource_calendar","hr.group_hr_user",1,0,0,0 +"access_hr_timesheet","hr.timesheet","model_hr_timesheet","hr.group_hr_user",1,1,1,1 +"access_hr_timesheet_manager","hr.timesheet manager","model_hr_timesheet","hr.group_hr_manager",1,1,1,1 +"access_hr_timesheet_group_manager","hr.timesheet.group.manager","model_hr_timesheet_group","hr.group_hr_manager",1,1,1,1 |
