diff options
| author | Vidhin Mehta <vme@tinyerp.com> | 2013-08-23 10:36:02 +0530 |
|---|---|---|
| committer | Vidhin Mehta <vme@tinyerp.com> | 2013-08-23 10:36:02 +0530 |
| commit | 75ddd5ccbec73c4a671b6a74efaa3d41dc2ea2db (patch) | |
| tree | 50ed3620df15e8533760f5d47e754a1d39c1e856 /addons/hr | |
| parent | 42f27a15275effd9c43dfe99e32c395ca6b3fd8a (diff) | |
| parent | a7f4b6aaa0359d12046e81183417c24f093cd7c3 (diff) | |
[MERGE]Trunk.
bzr revid: vme@tinyerp.com-20130823050602-33bqv07e7g8dhv7x
Diffstat (limited to 'addons/hr')
| -rw-r--r-- | addons/hr/__init__.py | 1 | ||||
| -rw-r--r-- | addons/hr/__openerp__.py | 4 | ||||
| -rw-r--r-- | addons/hr/hr.py | 105 | ||||
| -rw-r--r-- | addons/hr/hr_demo.xml | 10 | ||||
| -rw-r--r-- | addons/hr/hr_view.xml | 29 | ||||
| -rw-r--r-- | addons/hr/mail_hr_view.xml | 19 | ||||
| -rw-r--r-- | addons/hr/res_users.py | 65 | ||||
| -rw-r--r-- | addons/hr/res_users_view.xml | 20 | ||||
| -rw-r--r-- | addons/hr/static/description/crm_game_01.png (renamed from addons/hr/html/crm_game_01.png) | bin | 17867 -> 17867 bytes | |||
| -rw-r--r-- | addons/hr/static/description/crm_game_02.png (renamed from addons/hr/html/crm_game_02.png) | bin | 12887 -> 12887 bytes | |||
| -rw-r--r-- | addons/hr/static/description/crm_game_03.png (renamed from addons/hr/html/crm_game_03.png) | bin | 5800 -> 5800 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_appraisal.png (renamed from addons/hr/html/hr_appraisal.png) | bin | 43303 -> 43303 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_employee.png (renamed from addons/hr/html/hr_employee.png) | bin | 48997 -> 48997 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_expense.png (renamed from addons/hr/html/hr_expense.png) | bin | 45187 -> 45187 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_illu_01.png (renamed from addons/hr/html/hr_illu_01.png) | bin | 24366 -> 24366 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_illu_02.png (renamed from addons/hr/html/hr_illu_02.png) | bin | 22544 -> 22544 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_kanban.png (renamed from addons/hr/html/hr_kanban.png) | bin | 113589 -> 113589 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_recruitment.png (renamed from addons/hr/html/hr_recruitment.png) | bin | 92899 -> 92899 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_social.png (renamed from addons/hr/html/hr_social.png) | bin | 86616 -> 86616 bytes | |||
| -rw-r--r-- | addons/hr/static/description/hr_timesheet.png (renamed from addons/hr/html/hr_timesheet.png) | bin | 61578 -> 61578 bytes | |||
| -rw-r--r-- | addons/hr/static/description/icon.png (renamed from addons/hr/static/src/img/icon.png) | bin | 8676 -> 8676 bytes | |||
| -rw-r--r-- | addons/hr/static/description/index.html (renamed from addons/hr/html/index.html) | 2 | ||||
| -rw-r--r-- | addons/hr/static/src/css/hr.css | 5 | ||||
| -rw-r--r-- | addons/hr/static/src/js/suggestions.js | 78 | ||||
| -rw-r--r-- | addons/hr/static/src/xml/suggestions.xml | 36 |
25 files changed, 327 insertions, 47 deletions
diff --git a/addons/hr/__init__.py b/addons/hr/__init__.py index 02ac7f16fd9..fbd01761f39 100644 --- a/addons/hr/__init__.py +++ b/addons/hr/__init__.py @@ -23,5 +23,6 @@ import hr_department import hr import res_config +import res_users # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr/__openerp__.py b/addons/hr/__openerp__.py index b4b8e982845..b074a80aa88 100644 --- a/addons/hr/__openerp__.py +++ b/addons/hr/__openerp__.py @@ -59,6 +59,8 @@ You can manage: 'hr_installer.xml', 'hr_data.xml', 'res_config_view.xml', + 'mail_hr_view.xml', + 'res_users_view.xml', ], 'demo': ['hr_demo.xml'], 'test': [ @@ -69,5 +71,7 @@ You can manage: 'application': True, 'auto_install': False, 'css': [ 'static/src/css/hr.css' ], + 'js': [ 'static/src/js/suggestions.js' ], + 'qweb': [ 'static/src/xml/suggestions.xml' ], } # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/hr/hr.py b/addons/hr/hr.py index 7f704e42e5e..d19f1f7de8b 100644 --- a/addons/hr/hr.py +++ b/addons/hr/hr.py @@ -25,9 +25,11 @@ from openerp.modules.module import get_module_resource from openerp.osv import fields, osv from openerp.tools.translate import _ from openerp import tools +from openerp.tools.translate import _ _logger = logging.getLogger(__name__) + class hr_employee_category(osv.osv): def name_get(self, cr, uid, ids, context=None): @@ -49,9 +51,9 @@ class hr_employee_category(osv.osv): _name = "hr.employee.category" _description = "Employee Category" _columns = { - 'name': fields.char("Category", size=64, required=True), + 'name': fields.char("Employee Tag", size=64, required=True), 'complete_name': fields.function(_name_get_fnc, type="char", string='Name'), - 'parent_id': fields.many2one('hr.employee.category', 'Parent Category', select=True), + 'parent_id': fields.many2one('hr.employee.category', 'Parent Employee Tag', select=True), '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'), } @@ -127,7 +129,7 @@ class hr_job(osv.osv): } _sql_constraints = [ - ('name_company_uniq', 'unique(name, company_id)', 'The name of the job position must be unique per company!'), + ('name_company_uniq', 'unique(name, company_id, department_id)', 'The name of the job position must be unique per department in company!'), ] @@ -150,18 +152,21 @@ class hr_job(osv.osv): class hr_employee(osv.osv): _name = "hr.employee" _description = "Employee" + _order = 'name_related' _inherits = {'resource.resource': "resource_id"} _inherit = ['mail.thread'] + _mail_post_access = 'read' + def _get_image(self, cr, uid, ids, name, args, context=None): result = dict.fromkeys(ids, False) for obj in self.browse(cr, uid, ids, context=context): result[obj.id] = tools.image_get_resized_images(obj.image) return result - + def _set_image(self, cr, uid, id, name, value, args, context=None): return self.write(cr, uid, [id], {'image': tools.image_resize_image_big(value)}, context=context) - + _columns = { #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), @@ -171,12 +176,12 @@ class hr_employee(osv.osv): 'sinid': fields.char('SIN No', size=32, help="Social Insurance Number"), 'identification_id': fields.char('Identification No', size=32), 'otherid': fields.char('Other Id', size=64), - 'gender': fields.selection([('male', 'Male'),('female', 'Female')], 'Gender'), + 'gender': fields.selection([('male', 'Male'), ('female', 'Female')], 'Gender'), 'marital': fields.selection([('single', 'Single'), ('married', 'Married'), ('widower', 'Widower'), ('divorced', 'Divorced')], 'Marital Status'), - 'department_id':fields.many2one('hr.department', 'Department'), + 'department_id': fields.many2one('hr.department', 'Department'), 'address_id': fields.many2one('res.partner', 'Working Address'), 'address_home_id': fields.many2one('res.partner', 'Home Address'), - 'bank_account_id':fields.many2one('res.partner.bank', 'Bank Account Number', domain="[('partner_id','=',address_home_id)]", help="Employee bank salary account"), + 'bank_account_id': fields.many2one('res.partner.bank', 'Bank Account Number', domain="[('partner_id','=',address_home_id)]", help="Employee bank salary account"), 'work_phone': fields.char('Work Phone', size=32, readonly=False), 'mobile_phone': fields.char('Work Mobile', size=32, readonly=False), 'work_email': fields.char('Work Email', size=240), @@ -187,7 +192,7 @@ class hr_employee(osv.osv): 'child_ids': fields.one2many('hr.employee', 'parent_id', 'Subordinates'), 'resource_id': fields.many2one('resource.resource', 'Resource', ondelete='cascade', required=True), 'coach_id': fields.many2one('hr.employee', 'Coach'), - 'job_id': fields.many2one('hr.job', 'Job'), + 'job_id': fields.many2one('hr.job', 'Job Title'), # image: all image fields are base64 encoded and PIL-supported 'image': fields.binary("Photo", help="This field holds the image used as photo for the employee, limited to 1024x1024px."), @@ -207,25 +212,42 @@ class hr_employee(osv.osv): help="Small-sized photo of the employee. It is automatically "\ "resized as a 64x64px image, with aspect ratio preserved. "\ "Use this field anywhere a small image is required."), - 'passport_id':fields.char('Passport No', size=64), + 'passport_id': fields.char('Passport No', size=64), 'color': fields.integer('Color Index'), 'city': fields.related('address_id', 'city', type='char', string='City'), 'login': fields.related('user_id', 'login', type='char', string='Login', readonly=1), 'last_login': fields.related('user_id', 'date', type='datetime', string='Latest Connection', readonly=1), } - _order='name_related' + 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, + } def create(self, cr, uid, data, context=None): - employee_id = super(hr_employee, self).create(cr, uid, data, context=context) - try: - (model, mail_group_id) = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'mail', 'group_all_employees') - employee = self.browse(cr, uid, employee_id, context=context) - self.pool.get('mail.group').message_post(cr, uid, [mail_group_id], - body=_('Welcome to %s! Please help him/her take the first steps with OpenERP!') % (employee.name), - subtype='mail.mt_comment', context=context) - except: - pass # group deleted: do not push a message + if context is None: + context = {} + create_ctx = dict(context, mail_create_nolog=True) + employee_id = super(hr_employee, self).create(cr, uid, data, context=create_ctx) + employee = self.browse(cr, uid, employee_id, context=context) + 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 + ) return employee_id def unlink(self, cr, uid, ids, context=None): @@ -246,7 +268,7 @@ class hr_employee(osv.osv): company_id = self.pool.get('res.company').browse(cr, uid, company, context=context) address = self.pool.get('res.partner').address_get(cr, uid, [company_id.partner_id.id], ['default']) address_id = address and address['default'] or False - return {'value': {'address_id' : address_id}} + return {'value': {'address_id': address_id}} def onchange_department_id(self, cr, uid, ids, department_id, context=None): value = {'parent_id': False} @@ -259,17 +281,36 @@ class hr_employee(osv.osv): work_email = False if user_id: work_email = self.pool.get('res.users').browse(cr, uid, user_id, context=context).email - return {'value': {'work_email' : work_email}} - - 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, - } + return {'value': {'work_email': work_email}} + + 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) + + 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) + + 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 def _check_recursion(self, cr, uid, ids, context=None): level = 100 diff --git a/addons/hr/hr_demo.xml b/addons/hr/hr_demo.xml index 641d5b272cf..41b09c3aea3 100644 --- a/addons/hr/hr_demo.xml +++ b/addons/hr/hr_demo.xml @@ -91,14 +91,14 @@ <!--Employees--> <record id="employee_fp" model="hr.employee"> - <field name="name">Peter Parker</field> + <field name="name">Pieter Parker</field> <field name="user_id" ref="base.user_root"/> <field name="department_id" ref="dep_management"/> <field name="job_id" ref="hr.job_ceo"/> <field name="category_ids" eval="[(6, 0, [ref('employee_category_2')])]"/> <field name="work_location">Grand-Rosière</field> <field name="work_phone">+3281813700</field> - <field name="work_email">peter@openerp.com</field> + <field name="work_email">pieter@openerp.com</field> <field name="image">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</field> </record> @@ -139,7 +139,7 @@ </record> <record id="employee_stw" model="hr.employee"> - <field name="name">Liam Neeson</field> + <field name="name">Liam Nelson</field> <field name="department_id" ref="dep_rd"/> <field name="parent_id" ref="employee_al"/> <field name="job_id" ref="hr.job_developer"/> @@ -212,7 +212,7 @@ </record> <record id="employee_ngh" model="hr.employee"> - <field name="name">Famke Janssen</field> + <field name="name">Famke Jenssens</field> <field name="department_id" ref="dep_sales"/> <field name="parent_id" ref="employee_fp"/> <field name="job_id" ref="hr.job_marketing"/> @@ -255,7 +255,7 @@ </record> <record id="employee_jep" model="hr.employee"> - <field name="name">Jean Pierre</field> + <field name="name">Jean-Pierre Carnaud</field> <field name="department_id" ref="dep_ps"/> <field name="job_id" ref="hr.job_consultant"/> <field name="work_location">Grand-Rosière</field> diff --git a/addons/hr/hr_view.xml b/addons/hr/hr_view.xml index ccd11bc0dc2..05a21c2908a 100644 --- a/addons/hr/hr_view.xml +++ b/addons/hr/hr_view.xml @@ -27,6 +27,10 @@ </h1> <label for="category_ids" class="oe_edit_only" groups="base.group_hr_user"/> <field name="category_ids" widget="many2many_tags" placeholder="e.g. Part Time" groups="base.group_hr_user"/> + <label for="work_email" class="oe_edit_only"/> + <field name="work_email" widget="email"/> + <label for="work_phone" class="oe_edit_only"/> + <field name="work_phone"/> </div> <div class="oe_right oe_button_box" name="button_box"> <!-- Put here related buttons --> @@ -36,8 +40,6 @@ <group> <group string="Contact Information"> <field name="address_id" on_change="onchange_address_id(address_id)" context="{'show_address': 1}" options='{"always_reload": True, "highlight_first_line": True}'/> - <field name="work_email" widget="email"/> - <field name="work_phone"/> <field name="mobile_phone"/> <field name="work_location"/> </group> @@ -136,6 +138,9 @@ <field name="arch" type="xml"> <kanban> <field name="last_login"/> + <field name="message_is_follower"/> + <field name="message_follower_ids"/> + <field name="message_ids"/> <templates> <t t-name="kanban-box"> <div class="oe_employee_vignette"> @@ -154,10 +159,19 @@ </li> <li t-if="record.job_id.raw_value"><field name="job_id"/></li> <li t-if="record.work_location.raw_value"><field name="work_location"/></li> - <li t-if="record.work_phone.raw_value">Tel: <field name="work_phone"/></li> - <li t-if="record.mobile_phone.raw_value">Mobile: <field name="mobile_phone"/></li> <li t-if="record.work_email.raw_value"><a t-attf-href="mailto:#{record.work_email.value}"><field name="work_email"/></a></li> </ul> + <div class="oe_kanban_footer_left"> + <span title='Messages'><span class='oe_e'>9</span><t t-esc="record.message_ids.raw_value.length"/></span> + <span title='Followers'><span class='oe_e'>+</span><t t-esc="record.message_follower_ids.raw_value.length"/></span> + </div> + <div class="oe_followers" groups="base.group_user"> + <button t-if="record.message_is_follower.raw_value" name="action_unfollow" type="object" class="oe_follower oe_following"> + <span class="oe_unfollow">Unfollow</span> + <span class="oe_following">Following</span> + </button> + <button t-if="! record.message_is_follower.raw_value" name="action_follow" type="object" class="oe_follower oe_notfollow">Follow</button> + </div> </div> </div> <script> @@ -334,12 +348,10 @@ <h1><field name="name" class="oe_inline"/></h1> </div> <group> - <group> + <group name="job_data"> <field name="no_of_employee" groups="base.group_user"/> <field name="no_of_recruitment" on_change="on_change_expected_employee(no_of_recruitment,no_of_employee)"/> <field name="expected_employees" groups="base.group_user"/> - </group> - <group> <field name="company_id" widget="selection" groups="base.group_multi_company"/> <field name="department_id"/> </group> @@ -368,10 +380,9 @@ <tree string="Job"> <field name="name"/> <field name="department_id"/> - <field name="company_id" groups="base.group_multi_company"/> - <field name="expected_employees"/> <field name="no_of_employee"/> <field name="no_of_recruitment"/> + <field name="expected_employees"/> <field name="state"/> </tree> </field> diff --git a/addons/hr/mail_hr_view.xml b/addons/hr/mail_hr_view.xml new file mode 100644 index 00000000000..203878c7a77 --- /dev/null +++ b/addons/hr/mail_hr_view.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<openerp> + <data> + + <record id="mail.action_mail_inbox_feeds" model="ir.actions.client"> + <field name="params" eval=""{ + 'domain': [ + ('to_read', '=', True), + ('starred', '=', False), + ], + 'view_mailbox': True, + 'view_inbox': True, + 'read_action': 'read', + 'show_compose_message': True + }""/> + </record> + + </data> +</openerp>
\ No newline at end of file diff --git a/addons/hr/res_users.py b/addons/hr/res_users.py new file mode 100644 index 00000000000..c3550596281 --- /dev/null +++ b/addons/hr/res_users.py @@ -0,0 +1,65 @@ +from openerp.osv import fields, osv +from openerp.tools.translate import _ + + +class res_users(osv.Model): + """ Update of res.users class + - if adding groups to an user, check if base.group_user is in it + (member of 'Employee'), create an employee form linked to it. + """ + _name = 'res.users' + _inherit = ['res.users'] + + _columns = { + 'display_employees_suggestions': fields.boolean("Display Employees Suggestions"), + } + + _defaults = { + 'display_employees_suggestions': True, + } + + def __init__(self, pool, cr): + """ Override of __init__ to add access rights on + display_employees_suggestions fields. Access rights are disabled by + default, but allowed on some specific fields defined in + self.SELF_{READ/WRITE}ABLE_FIELDS. + """ + init_res = super(res_users, self).__init__(pool, cr) + # duplicate list to avoid modifying the original reference + self.SELF_WRITEABLE_FIELDS = list(self.SELF_WRITEABLE_FIELDS) + self.SELF_WRITEABLE_FIELDS.append('display_employees_suggestions') + # duplicate list to avoid modifying the original reference + self.SELF_READABLE_FIELDS = list(self.SELF_READABLE_FIELDS) + self.SELF_READABLE_FIELDS.append('display_employees_suggestions') + return init_res + + def stop_showing_employees_suggestions(self, cr, uid, user_id, context=None): + """Update display_employees_suggestions value to False""" + if context is None: + context = {} + self.write(cr, uid, user_id, {"display_employees_suggestions": False}, context) + + def _create_welcome_message(self, cr, uid, user, context=None): + """Do not welcome new users anymore, welcome new employees instead""" + return True + + def _message_post_get_eid(self, cr, uid, thread_id, context=None): + assert thread_id, "res.users does not support posting global messages" + if context and 'thread_model' in context: + context['thread_model'] = 'hr.employee' + if isinstance(thread_id, (list, tuple)): + thread_id = thread_id[0] + return self.pool.get('hr.employee').search(cr, uid, [('user_id', '=', thread_id)], context=context) + + def message_post(self, cr, uid, thread_id, context=None, **kwargs): + """ Redirect the posting of message on res.users to the related employee. + This is done because when giving the context of Chatter on the + various mailboxes, we do not have access to the current partner_id. """ + if kwargs.get('type') == 'email': + return super(res_users, self).message_post(cr, uid, thread_id, context=context, **kwargs) + employee_ids = self._message_post_get_eid(cr, uid, thread_id, context=context) + if not employee_ids: + pass # dpo something + for employee_id in employee_ids: + res = self.pool.get('hr.employee').message_post(cr, uid, employee_id, context=context, **kwargs) + return res diff --git a/addons/hr/res_users_view.xml b/addons/hr/res_users_view.xml new file mode 100644 index 00000000000..0843269e716 --- /dev/null +++ b/addons/hr/res_users_view.xml @@ -0,0 +1,20 @@ +<?xml version="1.0"?> +<openerp> + <data> + + <!-- Update user form !--> + <record id="view_users_form_mail" model="ir.ui.view"> + <field name="name">res.users.form.hr</field> + <field name="model">res.users</field> + <field name="inherit_id" ref="mail.view_users_form_mail"/> + <field name="arch" type="xml"> + <data> + <field name="display_groups_suggestions" position="after"> + <field name="display_employees_suggestions"/> + </field> + </data> + </field> + </record> + + </data> +</openerp> diff --git a/addons/hr/html/crm_game_01.png b/addons/hr/static/description/crm_game_01.png Binary files differindex a3cd109c2de..a3cd109c2de 100644 --- a/addons/hr/html/crm_game_01.png +++ b/addons/hr/static/description/crm_game_01.png diff --git a/addons/hr/html/crm_game_02.png b/addons/hr/static/description/crm_game_02.png Binary files differindex 1a747e1ffe8..1a747e1ffe8 100644 --- a/addons/hr/html/crm_game_02.png +++ b/addons/hr/static/description/crm_game_02.png diff --git a/addons/hr/html/crm_game_03.png b/addons/hr/static/description/crm_game_03.png Binary files differindex 2fd14886179..2fd14886179 100644 --- a/addons/hr/html/crm_game_03.png +++ b/addons/hr/static/description/crm_game_03.png diff --git a/addons/hr/html/hr_appraisal.png b/addons/hr/static/description/hr_appraisal.png Binary files differindex f0052bfda61..f0052bfda61 100644 --- a/addons/hr/html/hr_appraisal.png +++ b/addons/hr/static/description/hr_appraisal.png diff --git a/addons/hr/html/hr_employee.png b/addons/hr/static/description/hr_employee.png Binary files differindex eff8730863f..eff8730863f 100644 --- a/addons/hr/html/hr_employee.png +++ b/addons/hr/static/description/hr_employee.png diff --git a/addons/hr/html/hr_expense.png b/addons/hr/static/description/hr_expense.png Binary files differindex 7fbc35711e1..7fbc35711e1 100644 --- a/addons/hr/html/hr_expense.png +++ b/addons/hr/static/description/hr_expense.png diff --git a/addons/hr/html/hr_illu_01.png b/addons/hr/static/description/hr_illu_01.png Binary files differindex ad65bb9b407..ad65bb9b407 100644 --- a/addons/hr/html/hr_illu_01.png +++ b/addons/hr/static/description/hr_illu_01.png diff --git a/addons/hr/html/hr_illu_02.png b/addons/hr/static/description/hr_illu_02.png Binary files differindex b5416926793..b5416926793 100644 --- a/addons/hr/html/hr_illu_02.png +++ b/addons/hr/static/description/hr_illu_02.png diff --git a/addons/hr/html/hr_kanban.png b/addons/hr/static/description/hr_kanban.png Binary files differindex c0782d6adca..c0782d6adca 100644 --- a/addons/hr/html/hr_kanban.png +++ b/addons/hr/static/description/hr_kanban.png diff --git a/addons/hr/html/hr_recruitment.png b/addons/hr/static/description/hr_recruitment.png Binary files differindex 1951b54a6f2..1951b54a6f2 100644 --- a/addons/hr/html/hr_recruitment.png +++ b/addons/hr/static/description/hr_recruitment.png diff --git a/addons/hr/html/hr_social.png b/addons/hr/static/description/hr_social.png Binary files differindex 215d4e3ba70..215d4e3ba70 100644 --- a/addons/hr/html/hr_social.png +++ b/addons/hr/static/description/hr_social.png diff --git a/addons/hr/html/hr_timesheet.png b/addons/hr/static/description/hr_timesheet.png Binary files differindex d06c3a924ec..d06c3a924ec 100644 --- a/addons/hr/html/hr_timesheet.png +++ b/addons/hr/static/description/hr_timesheet.png diff --git a/addons/hr/static/src/img/icon.png b/addons/hr/static/description/icon.png Binary files differindex 742f3e53e67..742f3e53e67 100644 --- a/addons/hr/static/src/img/icon.png +++ b/addons/hr/static/description/icon.png diff --git a/addons/hr/html/index.html b/addons/hr/static/description/index.html index 0bc3db084a4..f97cb462fe3 100644 --- a/addons/hr/html/index.html +++ b/addons/hr/static/description/index.html @@ -17,7 +17,7 @@ Get all your HR operations managed easily: knowledge sharing, recruitments, appr Each need is provided by a specific app that you activate on demand. </p> <div class="oe_centeralign oe_websiteonly"> - <a href="http://www.openerp.com/start" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a> + <a href="http://www.openerp.com/start?app=hr" class="oe_button oe_big oe_tacky">Start your <span class="oe_emph">free</span> trial</a> </div> </div> </div> diff --git a/addons/hr/static/src/css/hr.css b/addons/hr/static/src/css/hr.css index 16657394736..951ec4d02e3 100644 --- a/addons/hr/static/src/css/hr.css +++ b/addons/hr/static/src/css/hr.css @@ -68,3 +68,8 @@ margin: 2px 0; padding: 0; } + +.openerp .oe_employee_vignette .oe_followers { + width: auto; + float: none; +} diff --git a/addons/hr/static/src/js/suggestions.js b/addons/hr/static/src/js/suggestions.js new file mode 100644 index 00000000000..3bc37e71344 --- /dev/null +++ b/addons/hr/static/src/js/suggestions.js @@ -0,0 +1,78 @@ +openerp.hr = function(session) { + var _t = session.web._t; + var QWeb = session.web.qweb; + + var suggestions = session.suggestions; + var removed_suggested_employee = session.suggestions.removed_suggested_employee = []; + + suggestions.Employees = session.web.Widget.extend({ + events: { + 'click .oe_suggestion_remove.oe_suggestion_employee': 'stop_employee_suggestion', + 'click .oe_suggestion_remove_item.oe_suggestion_employee': 'remove_employee_suggestion', + 'click .oe_suggestion_follow': 'follow_employee', + }, + + init: function () { + this._super(this, arguments); + this.hr_employee = new session.web.DataSetSearch(this, 'hr.employee'); + this.res_users = new session.web.DataSetSearch(this, 'res.users'); + this.employees = []; + }, + + start: function () { + this._super.apply(this, arguments); + return this.fetch_suggested_employee(); + }, + + fetch_suggested_employee: function () { + var self = this; + var employee = self.hr_employee.call('get_suggested_thread', {'removed_suggested_threads': removed_suggested_employee}).then(function (res) { + _(res).each(function (result) { + result['image']=self.session.url('/web/binary/image', {model: 'hr.employee', field: 'image_small', id: result.id}); + }); + self.employees = res; + }); + return $.when(employee).done(this.proxy('display_suggested_employees')); + }, + + display_suggested_employees: function () { + var suggested_employees = this.$('.oe_sidebar_suggestion.oe_suggestion_employee'); + if (suggested_employees) { + suggested_employees.remove(); + } + if (this.employees.length === 0) { + return this.$el.empty(); + } + return this.$el.empty().html(QWeb.render('hr.suggestions.employees', {'widget': this})); + }, + + follow_employee: function (event) { + var self = this; + var employee_id = parseInt($(event.currentTarget).attr('id'), 10); + return this.hr_employee.call('message_subscribe_users', [[employee_id], [this.session.uid], undefined]).then(function(res) { + self.fetch_suggested_employee(); + }); + }, + + remove_employee_suggestion: function (event) { + removed_suggested_employee.push($(event.currentTarget).attr('id')); + return this.fetch_suggested_employee(); + }, + + stop_employee_suggestion: function (event) { + var self = this; + return this.res_users.call('stop_showing_employees_suggestions', [this.session.uid]).then(function(res) { + self.$(".oe_sidebar_suggestion.oe_suggestion_employee").hide(); + }); + } + }); + + session.mail.WallSidebar.include({ + start: function () { + this._super.apply(this, arguments); + var sug_employees = new suggestions.Employees(this); + return sug_employees.appendTo(this.$('.oe_suggestions_employees')); + }, + }); + +}; diff --git a/addons/hr/static/src/xml/suggestions.xml b/addons/hr/static/src/xml/suggestions.xml new file mode 100644 index 00000000000..f3095627bae --- /dev/null +++ b/addons/hr/static/src/xml/suggestions.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="UTF-8"?> +<template> + + <!-- Employees placeholder in sidebar --> + <t t-extend="mail.wall.sidebar"> + <t t-jquery=".oe_mail_wall_sidebar" t-operation="append"> + <div class="oe_suggestions_employees"></div> + </t> + </t> + + <!-- Suggested employees --> + <div t-name="hr.suggestions.employees" class="oe_sidebar_suggestion oe_suggestion_employee"> + <div class="oe_suggest_title"> + <a class="oe_suggestion_remove oe_suggestion_employee oe_e">X</a> + <h2>Suggested Employees</h2> + </div> + <div class="oe_suggest_items"> + <t t-foreach="widget.employees" t-as="result"> + <div class="oe_suggested_item"> + <div class="oe_suggested_item_image"> + <a t-attf-href="#model=hr.employee&id=#{result.id}"> + <img t-attf-src="{result.image}" t-attf-alt="{result.name}"/> + </a> + </div> + <div class="oe_suggested_item_content"> + <a class="oe_suggestion_item_name" t-attf-href="#model=hr.employee&id=#{result.id}"><t t-esc="result.name"/></a> + <a class="oe_suggestion_remove_item oe_suggestion_employee oe_e" t-attf-id="{result.id}">X</a> + <br/> + <button class="oe_suggestion_follow" t-att-id="result.id">Follow</button> + </div> + </div> + </t> + </div> + </div> + +</template> |
