diff options
| author | Francois (fge) <fge@odoo.com> | 2020-08-14 09:15:13 +0000 |
|---|---|---|
| committer | Francois (fge) <fge@odoo.com> | 2020-08-14 14:51:41 +0000 |
| commit | c06bb52f57f4719af7da944de2971556d03caff1 (patch) | |
| tree | 010330740e97f7edfa7265937f6d1208171545c3 | |
| parent | 05c1cb69778f45fda3f76426c7b5a89969f845ab (diff) | |
[IMP]hr_recruitment: Back2Basic - Improve Recruitment usability
Added a new tour for the module hr_recruitment
Hr.job:
Form view:
- Using a notebook view for increased clarity
Kanban view:
- Added a toggle button to publish/unpublish a job offer.
- In the menu, added the « Create Interview Form » button to create an interview form.
Hr.applicant:
Generale:
- Use of the "Applicant: Acknowledgement" template by default when an application is moved to the "First Interview" stage.
Form view:
- Possibility to consult an interview after this one and not before
- The "CREATE EMPLOYEE" button no longer directly creates an employee. The employee will be created if the "SAVE" button is pressed.
Hr.employee:
Generale:
- Added of two new certifications.
And some other minor style and name changes.
closes odoo/odoo#55928
Related: odoo/enterprise#12420
Signed-off-by: Yannick Tivisse (yti) <yti@odoo.com>
18 files changed, 240 insertions, 96 deletions
diff --git a/addons/hr/models/hr_employee.py b/addons/hr/models/hr_employee.py index 8225c22f59d..5cba3626917 100644 --- a/addons/hr/models/hr_employee.py +++ b/addons/hr/models/hr_employee.py @@ -82,8 +82,10 @@ class HrEmployeePrivate(models.Model): visa_expire = fields.Date('Visa Expire Date', groups="hr.group_hr_user", tracking=True) additional_note = fields.Text(string='Additional Note', groups="hr.group_hr_user", tracking=True) certificate = fields.Selection([ + ('graduate', 'Graduate'), ('bachelor', 'Bachelor'), ('master', 'Master'), + ('doctor', 'Doctor'), ('other', 'Other'), ], 'Certificate Level', default='other', groups="hr.group_hr_user", tracking=True) study_field = fields.Char("Field of Study", groups="hr.group_hr_user", tracking=True) diff --git a/addons/hr/views/hr_employee_views.xml b/addons/hr/views/hr_employee_views.xml index 43785f2110f..abb9350790e 100644 --- a/addons/hr/views/hr_employee_views.xml +++ b/addons/hr/views/hr_employee_views.xml @@ -38,7 +38,7 @@ <field name="name">hr.employee.form</field> <field name="model">hr.employee</field> <field name="arch" type="xml"> - <form string="Employee" js_class="hr_employee_form"> + <form string="Employee" js_class="hr_employee_form" class='o_employee_form'> <field name="active" invisible="1"/> <field name="user_partner_id" invisible="1"/> <field name="hr_presence_state" invisible="1"/> diff --git a/addons/hr/views/hr_job_views.xml b/addons/hr/views/hr_job_views.xml index 3e0a6170e5d..a97ec87c190 100644 --- a/addons/hr/views/hr_job_views.xml +++ b/addons/hr/views/hr_job_views.xml @@ -18,22 +18,28 @@ <label for="name" class="oe_edit_only"/> <h1><field name="name" placeholder="e.g. Sales Manager"/></h1> </div> - <group> - <group name="recruitment"> - <field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/> - <field name="department_id"/> - </group> - <group> - <field name="no_of_recruitment"/> - </group> - </group> - <div attrs="{'invisible': [('state', '!=', 'recruit')]}"> - <label for="description"/> - <field name="description"/> - </div> + <notebook> + <page string="Job Description"> + <div attrs="{'invisible': [('state', '!=', 'recruit')]}"> + <label for="description"/> + <field name="description"/> + </div> + </page> + <page string="Recruitment"> + <group> + <group name="recruitment"> + <field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/> + <field name="department_id"/> + </group> + <group> + <field name="no_of_recruitment"/> + </group> + </group> + </page> + </notebook> </sheet> <div class="oe_chatter"> - <field name="message_follower_ids"/> + <field name="message_follower_ids" options="{'open_attachments': True}"/> </div> </form> </field> diff --git a/addons/hr_recruitment/data/hr_recruitment_data.xml b/addons/hr_recruitment/data/hr_recruitment_data.xml index 5a07d1a88bb..4efeb5bab4c 100644 --- a/addons/hr_recruitment/data/hr_recruitment_data.xml +++ b/addons/hr_recruitment/data/hr_recruitment_data.xml @@ -351,6 +351,7 @@ <record model="hr.recruitment.stage" id="stage_job2"> <field name="name">First Interview</field> <field name="sequence">2</field> + <field name="template_id" ref="email_template_data_applicant_congratulations"/> </record> <record model="hr.recruitment.stage" id="stage_job3"> <field name="name">Second Interview</field> diff --git a/addons/hr_recruitment/models/hr_employee.py b/addons/hr_recruitment/models/hr_employee.py index a6f44e22da8..8640872d37d 100644 --- a/addons/hr_recruitment/models/hr_employee.py +++ b/addons/hr_recruitment/models/hr_employee.py @@ -1,6 +1,7 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. from odoo import api, fields, models +from odoo.tools.translate import _ from datetime import timedelta @@ -9,6 +10,7 @@ class HrEmployee(models.Model): newly_hired_employee = fields.Boolean('Newly hired employee', compute='_compute_newly_hired_employee', search='_search_newly_hired_employee') + applicant_id = fields.One2many('hr.applicant', 'emp_id', 'Applicant') def _compute_newly_hired_employee(self): now = fields.Datetime.now() @@ -20,3 +22,13 @@ class HrEmployee(models.Model): ('create_date', '>', fields.Datetime.now() - timedelta(days=90)) ]) return [('id', 'in', employees.ids)] + + @api.model + def create(self, vals): + new_employee = super(HrEmployee, self).create(vals) + if new_employee.applicant_id: + new_employee.applicant_id.message_post_with_view( + 'hr_recruitment.applicant_hired_template', + values={'applicant': new_employee.applicant_id}, + subtype_id=self.env.ref("hr_recruitment.mt_applicant_hired").id) + return new_employee diff --git a/addons/hr_recruitment/models/hr_job.py b/addons/hr_recruitment/models/hr_job.py index 7094d529721..edf7d025ad5 100644 --- a/addons/hr_recruitment/models/hr_job.py +++ b/addons/hr_recruitment/models/hr_job.py @@ -30,7 +30,7 @@ class Job(models.Model): manager_id = fields.Many2one( 'hr.employee', related='department_id.manager_id', string="Department Manager", readonly=True, store=True) - user_id = fields.Many2one('res.users', "Responsible", tracking=True) + user_id = fields.Many2one('res.users', "Recruiter", tracking=True) hr_responsible_id = fields.Many2one( 'res.users', "HR Responsible", tracking=True, help="Person responsible of validating the employee's contracts.") diff --git a/addons/hr_recruitment/models/hr_recruitment.py b/addons/hr_recruitment/models/hr_recruitment.py index febde49d78e..4db6da063af 100644 --- a/addons/hr_recruitment/models/hr_recruitment.py +++ b/addons/hr_recruitment/models/hr_recruitment.py @@ -114,8 +114,8 @@ class Applicant(models.Model): categ_ids = fields.Many2many('hr.applicant.category', string="Tags") company_id = fields.Many2one('res.company', "Company", compute='_compute_company', store=True, readonly=False, tracking=True) user_id = fields.Many2one( - 'res.users', "Responsible", compute='_compute_user', - tracking=True, store=True, readonly=False) + 'res.users', "Recruiter", compute='_compute_user', + tracking=True, default=lambda self: self.env.uid, store=True, readonly=False) date_closed = fields.Datetime("Closed", compute='_compute_date_closed', store=True, index=True) date_open = fields.Datetime("Assigned", readonly=True, index=True) date_last_stage_update = fields.Datetime("Last Stage Update", index=True, default=fields.Datetime.now) @@ -308,11 +308,28 @@ class Applicant(models.Model): res = super(Applicant, self).write(vals) return res - @api.model def get_empty_list_help(self, help): - return super(Applicant, self.with_context(empty_list_help_model='hr.job', - empty_list_help_id=self.env.context.get('default_job_id'), - empty_list_help_document_name=_("job applicant"))).get_empty_list_help(help) + if 'active_id' in self.env.context: + alias_id = self.env['hr.job'].browse(self.env.context['active_id']).alias_id + else: + alias_id = False + + nocontent_values = { + 'help_title': _('No application yet'), + 'para_1': _('Let people apply by email to save time.') , + 'para_2': _('Attachments, like resumes, get indexed automatically.'), + } + nocontent_body = """ + <p class="o_view_nocontent_empty_folder">%(help_title)s</p> + <p>%(para_1)s<br/>%(para_2)s</p>""" + + if alias_id and alias_id.alias_domain and alias_id.alias_name: + email = alias_id.display_name + email_link = "<a href='mailto:%s'>%s</a>" % (email, email) + nocontent_values['email_link'] = email_link + nocontent_body += """<p class="o_copy_paste_email">%(email_link)s</p>""" + + return nocontent_body % nocontent_values def action_makeMeeting(self): """ This opens Meeting's calendar view to schedule meeting on current applicant @@ -454,33 +471,24 @@ class Applicant(models.Model): applicant.partner_id = new_partner_id address_id = new_partner_id.address_get(['contact'])['contact'] if applicant.partner_name or contact_name: - employee = self.env['hr.employee'].create({ - 'name': applicant.partner_name or contact_name, - 'job_id': applicant.job_id.id or False, - 'job_title': applicant.job_id.name, + employee_data = { + 'default_name': applicant.partner_name or contact_name, + 'default_job_id': applicant.job_id.id, + 'default_job_title': applicant.job_id.name, 'address_home_id': address_id, - 'department_id': applicant.department_id.id or False, - 'address_id': applicant.company_id and applicant.company_id.partner_id + 'default_department_id': applicant.department_id.id or False, + 'default_address_id': applicant.company_id and applicant.company_id.partner_id and applicant.company_id.partner_id.id or False, - 'work_email': applicant.department_id and applicant.department_id.company_id + 'default_work_email': applicant.department_id and applicant.department_id.company_id and applicant.department_id.company_id.email or False, - 'work_phone': applicant.department_id and applicant.department_id.company_id - and applicant.department_id.company_id.phone or False}) - applicant.write({'emp_id': employee.id}) - if applicant.job_id: - applicant.job_id.write({'no_of_hired_employee': applicant.job_id.no_of_hired_employee + 1}) - applicant.job_id.message_post( - body=_('New Employee %s Hired', applicant.partner_name if applicant.partner_name else applicant.name), - subtype_xmlid="hr_recruitment.mt_job_applicant_hired") - applicant.message_post_with_view( - 'hr_recruitment.applicant_hired_template', - values={'applicant': applicant}, - subtype_id=self.env.ref("hr_recruitment.mt_applicant_hired").id) - + 'default_work_phone': applicant.department_id.company_id.phone, + 'form_view_initial_mode': 'edit', + 'default_applicant_id': applicant.ids, + } + employee_action = self.env.ref('hr.open_view_employee_list') dict_act_window = employee_action.read([])[0] - dict_act_window['context'] = {'form_view_initial_mode': 'edit'} - dict_act_window['res_id'] = employee.id + dict_act_window['context'] = employee_data return dict_act_window def archive_applicant(self): diff --git a/addons/hr_recruitment/static/src/js/tours/hr_recruitment.js b/addons/hr_recruitment/static/src/js/tours/hr_recruitment.js index 1939b5baf6c..92cc7f8ddd6 100644 --- a/addons/hr_recruitment/static/src/js/tours/hr_recruitment.js +++ b/addons/hr_recruitment/static/src/js/tours/hr_recruitment.js @@ -6,36 +6,97 @@ var tour = require('web_tour.tour'); var _t = core._t; -tour.register('hr_recruitment_tour', [tour.stepUtils.showAppsMenuItem(), { +tour.register('hr_recruitment_tour',{ + url: "/web", + rainbowManMessage: _t("<div>Great job! You hired a new colleague!</div><div>Try the Website app to publish job offers online.</div>"), +}, [tour.stepUtils.showAppsMenuItem(), { trigger: '.o_app[data-menu-xmlid="hr_recruitment.menu_hr_recruitment_root"]', - content: _t('Want to <b>start recruiting</b> like a pro? <i>Start here.</i>'), + content: _t("Let's have a look at how to <b>improve</b> your <b>hiring process</b>."), position: 'right', edition: 'community' }, { trigger: '.o_app[data-menu-xmlid="hr_recruitment.menu_hr_recruitment_root"]', - content: _t('Want to <b>start recruiting</b> like a pro? <i>Start here.</i>'), + content: _t("Let's have a look at how to <b>improve</b> your <b>hiring process</b>."), position: 'bottom', edition: 'enterprise' }, { trigger: ".o-kanban-button-new", - extra_trigger: '.o_hr_recruitment_kanban', - content: _t("Click here to create a new job position."), - position: "bottom" + content: _t("Create your first Job Position."), + position: "bottom", + width: 195 +}, { + trigger: ".o_job_name", + extra_trigger: '.o_hr_job_simple_form', + content: _t("What do you want to recruit today? Choose a job title..."), + position: "right" +}, { + trigger: ".o_job_alias", + extra_trigger: '.o_hr_job_simple_form', + content: _t("Choose an application email."), + position: "right" +}, { + trigger: '.o_create_job', + content: _t('Let\'s create the position. An email will be setup for applications, and a public job description, if you use the Website app.'), + position: 'bottom', + run: function (actions) { + actions.auto('.modal:visible .btn.btn-primary'); + }, }, { trigger: ".oe_kanban_action_button", extra_trigger: '.o_hr_recruitment_kanban', - content: _t("Let\'s have a look at the <b>applications pipeline</b> for this job position."), + content: _t("Let\'s have a look at the applications pipeline."), + position: "bottom" +}, { + trigger: ".o_copy_paste_email", + content: _t("Copy this email address, to paste it in your email composer, to apply."), position: "bottom" }, { trigger: ".breadcrumb-item:not(.active):last", extra_trigger: '.o_kanban_applicant', - content: _t("Use the breadcrumbs to <b>go back to the dashboard</b>."), + content: _t("Let’s go back to the dashboard."), position: "bottom" }, { - trigger: ".o_job_alias", + trigger: ".oe_kanban_action_button", extra_trigger: '.o_hr_recruitment_kanban', - content: _t("Try to send an email to this address, it will create an application automatically."), + content: _t("<b>Did you apply by sending an email?</b> Check incoming applications."), position: "bottom" +}, { + trigger: ".oe_kanban_card", + extra_trigger: '.o_kanban_applicant', + content: _t("<b>Drag this card</b>, to qualify him for a first interview."), + position: "bottom", + run: "drag_and_drop .o_kanban_group:eq(1) ", +}, { + trigger: ".oe_kanban_card", + extra_trigger: '.o_kanban_applicant', + content: _t("<b>Click to view</b> the application."), + position: "bottom" +}, { + trigger: ".o_Chatter .o_ChatterTopbar_buttonSendMessage", + extra_trigger: '.o_applicant_form', + content: _t("<div><b>Try to send an email</b> to the applicant.</div><div><i>Tips: All emails sent or received are saved in the history here</i>"), + position: "bottom" +}, { + trigger: ".o_Chatter .o_Composer_buttonSend", + extra_trigger: '.o_applicant_form', + content: _t("Send your email. Followers will get a copy of the communication."), + position: "bottom" +}, { + trigger: ".o_Chatter .o_ChatterTopbar_buttonLogNote", + extra_trigger: '.o_applicant_form', + content: _t("Or talk about this applicant privately with your colleagues."), + position: "bottom" +}, { + trigger: ".o_create_employee", + extra_trigger: '.o_applicant_form', + content: _t("Let’s create this new employee now."), + position: "bottom" +}, { + trigger: ".o_form_button_save", + extra_trigger: ".o_employee_form", + content: _t("Save it !"), + position: "bottom", + width: 80 }]); }); diff --git a/addons/hr_recruitment/static/src/scss/hr_job.scss b/addons/hr_recruitment/static/src/scss/hr_job.scss index 15a09a9bb3d..3025c1bdb71 100644 --- a/addons/hr_recruitment/static/src/scss/hr_job.scss +++ b/addons/hr_recruitment/static/src/scss/hr_job.scss @@ -17,6 +17,7 @@ padding: 5px; font-size: small; z-index: unset; + height: auto; } } .ribbon-top-right { @@ -51,10 +52,13 @@ } div:last-child { justify-content: flex-end; - padding-right: 16px; text-align: right; } - + .o_link_trackers{ + .fa{ + color: $o-brand-primary; + } + } .o_value { font-weight: 800; } diff --git a/addons/hr_recruitment/views/hr_job_views.xml b/addons/hr_recruitment/views/hr_job_views.xml index 3b6c6dbcc4c..8bbbb7e8b7b 100644 --- a/addons/hr_recruitment/views/hr_job_views.xml +++ b/addons/hr_recruitment/views/hr_job_views.xml @@ -68,8 +68,10 @@ <div name="kanban_boxes" class="row o_recruitment_kanban_boxes"> <div class="o_recruitment_kanban_box o_kanban_primary_bottom bottom_block" style="padding-left:8px;"> <div class="col-6"></div> - <div class="col-6"> - <a type="action" name="%(action_hr_job_sources)d">Link Trackers</a> + <div class="col-6 o_link_trackers"> + <a role="button" name="%(hr_recruitment.action_hr_job_sources)d" type="action" class="btn btn-sm "> + <span title="Link Trackers"><i class="fa fa-lg fa-envelope" role="img" aria-label="Link Trackers"/></span> + </a> </div> </div> </div> diff --git a/addons/hr_recruitment/views/hr_recruitment_templates.xml b/addons/hr_recruitment/views/hr_recruitment_templates.xml index 7eb215e3e67..a4fce72861d 100644 --- a/addons/hr_recruitment/views/hr_recruitment_templates.xml +++ b/addons/hr_recruitment/views/hr_recruitment_templates.xml @@ -5,11 +5,11 @@ <xpath expr="." position="inside"> <link rel="stylesheet" type="text/scss" href="/hr_recruitment/static/src/scss/hr_job.scss"/> <script type="text/javascript" src="/hr_recruitment/static/src/js/recruitment.js"></script> + <script type="text/javascript" src="/hr_recruitment/static/src/js/tours/hr_recruitment.js"></script> </xpath> </template> <template id="assets_tests" name="HR Recruitment Assets Tests" inherit_id="web.assets_tests"> <xpath expr="." position="inside"> - <script type="text/javascript" src="/hr_recruitment/static/src/js/tours/hr_recruitment.js"></script> </xpath> </template> </data> diff --git a/addons/hr_recruitment/views/hr_recruitment_views.xml b/addons/hr_recruitment/views/hr_recruitment_views.xml index a71088997b2..d973473bce7 100644 --- a/addons/hr_recruitment/views/hr_recruitment_views.xml +++ b/addons/hr_recruitment/views/hr_recruitment_views.xml @@ -29,22 +29,24 @@ <field name="last_stage_id" invisible="1"/> <field name="create_date" readonly="1" widget="date" optional="show"/> <field name="date_last_stage_update" invisible="1"/> - <field name="name" readonly="1"/> <field name="partner_name" readonly="1"/> - <field name="email_from" readonly="1" optional="hide"/> + <field name="name" readonly="1"/> + <field name="partner_mobile" widget="phone" readonly="1" optional="show"/> <field name="partner_phone" widget="phone" readonly="1" optional="hide"/> + <field name="email_from" readonly="1" optional="hide"/> <field name="job_id"/> - <field name="stage_id"/> + <field name="categ_ids" widget="many2many_tags" options="{'color_field': 'color'}" optional="show"/> + <field name="priority" widget="priority" optional="show"/> <field name="medium_id" optional="hide"/> <field name="source_id" readonly="1" optional="hide"/> - <field name="priority" widget="priority" optional="show"/> - <field name="salary_expected" optional="show"/> + <field name="salary_expected" optional="hide"/> <field name="salary_proposed" optional="hide"/> <field name="type_id" invisible="1"/> - <field name="availability" optional="show"/> + <field name="availability" optional="hide"/> <field name="department_id" invisible="context.get('invisible_department', True)" readonly="1"/> - <field name="user_id" widget="many2one_avatar_user" optional="hide"/> - <field name="company_id" groups="base.group_multi_company" readonly="1"/> + <field name="user_id" widget="many2one_avatar_user" optional="show"/> + <field name="company_id" groups="base.group_multi_company" readonly="1" optional="hide"/> + <field name="stage_id"/> </tree> </field> </record> @@ -69,10 +71,10 @@ <field name="name">Jobs - Recruitment Form</field> <field name="model">hr.applicant</field> <field name="arch" type="xml"> - <form string="Jobs - Recruitment Form"> + <form string="Jobs - Recruitment Form" class="o_applicant_form"> <header> <button string="Create Employee" name="create_employee_from_applicant" type="object" - class="oe_highlight" attrs="{'invisible': ['|',('emp_id', '!=', False),('active', '=', False)]}" confirm="Are you sure?"/> + class="oe_highlight o_create_employee" attrs="{'invisible': ['|',('emp_id', '!=', False),('active', '=', False)]}"/> <button string="Refuse" name="toggle_active" type="object" attrs="{'invisible': [('active', '=', False)]}"/> <button string="Restore" name="toggle_active" type="object" attrs="{'invisible': [('active', '=', True)]}"/> <field name="stage_id" widget="statusbar" options="{'clickable': '1', 'fold_field': 'fold'}" attrs="{'invisible': [('active', '=', False),('emp_id', '=', False)]}"/> @@ -152,7 +154,7 @@ <div class="oe_chatter"> <field name="message_follower_ids"/> <field name="activity_ids"/> - <field name="message_ids" options="{'post_refresh': 'recipients', 'open_attachments': True}"/> + <field name="message_ids" options="{'open_attachments': True}"/> </div> </form> </field> @@ -229,6 +231,17 @@ </field> </record> + <record id="hr_recruitment_source_view_search" model="ir.ui.view"> + <field name="name">hr.recruitment.source.view.search</field> + <field name="model">hr.recruitment.source</field> + <field name="arch" type="xml"> + <search string="Search Source"> + <field name="source_id"/> + <field name="job_id"/> + </search> + </field> + </record> + <record model="ir.ui.view" id="hr_applicant_calendar_view"> <field name="name">Hr Applicants Calendar</field> <field name="model">hr.applicant</field> @@ -287,14 +300,14 @@ <div t-attf-class="{{!selection_mode ? 'oe_kanban_color_' + kanban_getcolor(record.color.raw_value) : ''}} oe_kanban_card oe_kanban_global_click oe_applicant_kanban oe_semantic_html_override"> <span class="badge badge-pill badge-danger pull-right mr-4" attrs="{'invisible': [('active', '=', True)]}">Refused</span> <div class="o_dropdown_kanban dropdown"> - <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu"> + <a class="dropdown-toggle o-no-caret btn" role="button" data-toggle="dropdown" href="#" aria-label="Dropdown menu" title="Dropdown menu" data-display="static"> <span class="fa fa-ellipsis-v"/> </a> <div class="dropdown-menu" role="menu"> <t t-if="widget.deletable"><a role="menuitem" type="delete" class="dropdown-item">Delete</a></t> <a role="menuitem" name="action_makeMeeting" type="object" class="dropdown-item">Schedule Interview</a> <div role="separator" class="dropdown-divider"></div> - <ul class="oe_kanban_colorpicker" data-field="color"/> + <ul class="oe_kanban_colorpicker text-center" data-field="color"/> </div> </div> <div class="oe_kanban_content"> @@ -327,7 +340,7 @@ <t t-esc="record.attachment_number.raw_value"/> </span> </a> - <div class="o_kanban_state_with_padding"> + <div class="o_kanban_state_with_padding ml-1 mr-2" > <field name="kanban_state" widget="kanban_state_selection"/> <field name="legend_normal" invisible="1"/> <field name="legend_blocked" invisible="1"/> @@ -387,13 +400,13 @@ <field name="name">Jobs Sources</field> <field name="res_model">hr.recruitment.source</field> <field name="view_mode">tree</field> - <field name="domain">[('job_id', '=', active_id)]</field> - <field name="context">{'default_job_id': active_id}</field> + <field name="search_view_id" ref="hr_recruitment_source_view_search"/> + <field name="context">{'search_default_job_id': [active_id], 'default_job_id': active_id}</field> <field name="help" type="html"> <p class="o_view_nocontent_smiling_face"> - Create some aliases to track where applicants come from + Want to analyse where applications come from ? </p><p> - These aliases can be emails or urls for every source. When the applicant arrives here through one of these you'll know where he came from. + Use emails and links trackers </p> </field> </record> @@ -416,21 +429,21 @@ <field name="model">hr.job</field> <field name="priority">200</field> <field name="arch" type="xml"> - <form string="Create a Job Position"> + <form string="Create a Job Position" class="o_hr_job_simple_form" > <sheet> <group> - <field name="name" class="oe_inline" placeholder="e.g. Sales Manager"/> + <field name="name" class="o_job_name oe_inline" placeholder="e.g. Sales Manager"/> <label for="alias_name" string="Application email" attrs="{'invisible': [('alias_domain', '=', False)]}" help="Define a specific contact address for this job position. If you keep it empty, the default email address will be used which is in human resources settings"/> <div name="alias_def" attrs="{'invisible': [('alias_domain', '=', False)]}"> <field name="alias_id" class="oe_read_only" string="Email Alias" required="0"/> <div class="oe_edit_only" name="edit_alias"> - <field name="alias_name" class="oe_inline"/>@<field name="alias_domain" class="oe_inline" readonly="1"/> + <field name="alias_name" class="oe_inline o_job_alias" placeholder="e.g. sales-manager"/>@<field name="alias_domain" class="oe_inline" readonly="1"/> </div> <div class="text-muted" attrs="{'invisible': [('alias_domain', '=', False)]}">Applicants can send resume to this email address,<br/>it will create an application automatically</div> </div> </group> <footer> - <button string="Create" name="close_dialog" type="object" class="btn-primary"/> + <button string="Create" name="close_dialog" type="object" class="btn-primary o_create_job"/> <button string="Discard" class="btn-secondary" special="cancel"/> </footer> </sheet> @@ -858,11 +871,11 @@ action = act <field name="name">hr.recruitment.source.tree</field> <field name="model">hr.recruitment.source</field> <field name="arch" type="xml"> - <tree string="Sources of Applicants" editable="top" class="o_recruitment_list"> - <field name="source_id" placeholder="e.g. LinkedIn"/> - <field name="job_id"/> - <button name="create_alias" title="Generate email alias" type="object" icon="fa-repeat" /> - <field name="email"/> + <tree string="Sources of Applicants" editable="top" class="o_recruitment_list" sample="1"> + <field name="source_id" placeholder="e.g. LinkedIn" decoration-bf="1" attrs="{'readonly': [('id', '!=', False)]}"/> + <field name="job_id" attrs="{'readonly': [('id', '!=', False)]}"/> + <field name="email" attrs="{'invisible': [('email', '=', False)]}" widget="email"/> + <button name="create_alias" string="Generate Email" class="btn btn-primary" type="object" attrs="{'invisible': [('email', '!=', False)]}"/> </tree> </field> </record> diff --git a/addons/hr_recruitment_survey/models/hr_job.py b/addons/hr_recruitment_survey/models/hr_job.py index 32377181af8..60e7557e550 100644 --- a/addons/hr_recruitment_survey/models/hr_job.py +++ b/addons/hr_recruitment_survey/models/hr_job.py @@ -1,6 +1,6 @@ # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models +from odoo import fields, models, _ class Job(models.Model): @@ -12,3 +12,21 @@ class Job(models.Model): def action_print_survey(self): return self.survey_id.action_print_survey() + + def action_new_survey(self): + self.ensure_one() + survey = self.env['survey.survey'].create({ + 'title': _("Interview Form : %s") % self.name, + }) + self.write({'survey_id': survey.id}) + + action = { + 'name': _('Survey'), + 'view_mode': 'form,tree', + 'res_model': 'survey.survey', + 'type': 'ir.actions.act_window', + 'context': {'form_view_initial_mode': 'edit'}, + 'res_id': survey.id, + } + + return action diff --git a/addons/hr_recruitment_survey/views/hr_applicant_views.xml b/addons/hr_recruitment_survey/views/hr_applicant_views.xml index 66dc2a8c268..2bc997866ec 100644 --- a/addons/hr_recruitment_survey/views/hr_applicant_views.xml +++ b/addons/hr_recruitment_survey/views/hr_applicant_views.xml @@ -32,12 +32,12 @@ </button> <button name="action_print_survey" class="oe_stat_button" - icon="fa-print" + icon="fa-pencil-square-o" type="object" - help="Print interview report" - attrs="{'invisible':[('survey_id','=',False)]}"> + help="See interview report" + attrs="{'invisible':['|',('survey_id','=',False),('response_id','=',False)]}"> <div class="o_field_widget o_stat_info"> - <span class="o_stat_text">Print</span> + <span class="o_stat_text">Consult</span> <span class="o_stat_text">Interview</span> </div> </button> diff --git a/addons/hr_recruitment_survey/views/hr_job_views.xml b/addons/hr_recruitment_survey/views/hr_job_views.xml index 0b147acc90a..a89ff06448e 100644 --- a/addons/hr_recruitment_survey/views/hr_job_views.xml +++ b/addons/hr_recruitment_survey/views/hr_job_views.xml @@ -24,8 +24,8 @@ <field name="survey_id"/> </xpath> <xpath expr='//a[@name="edit_job"]' position="after"> - <a t-if="record.survey_id.raw_value" name="action_print_survey" type="object" title="Display Interview Form">Interview Form</a> - <span t-if="!record.survey_id.raw_value">No Interview Form</span> + <a t-if="record.survey_id.raw_value" name="action_print_survey" type="object" title="Display Interview Form">Preview Interview</a> + <a t-if="!record.survey_id.raw_value" name="action_new_survey" type="object" title="Create Interview Form">Create Interview Form</a> </xpath> </field> </record> diff --git a/addons/mail/static/src/js/basic_view.js b/addons/mail/static/src/js/basic_view.js index 6d74903e19c..c8af4a75dd0 100644 --- a/addons/mail/static/src/js/basic_view.js +++ b/addons/mail/static/src/js/basic_view.js @@ -17,7 +17,8 @@ BasicView.include({ hasRecordReloadOnAttachmentsChanged: post_refresh === 'always', hasRecordReloadOnMessagePosted: !!post_refresh, hasRecordReloadOnFollowersUpdate: !!followers_post_refresh, - isActivityBoxVisible: this._getFieldOption('message_ids', 'open_attachments', false), + isActivityBoxVisible: this._getFieldOption('message_ids', 'open_attachments', false) + || this._getFieldOption('message_follower_ids', 'open_attachments', false), }; const fieldsInfo = this.fieldsInfo[this.viewType]; this.rendererParams.chatterFields = this.chatterFields; diff --git a/addons/website_hr_recruitment/views/hr_job_views.xml b/addons/website_hr_recruitment/views/hr_job_views.xml index 744ff1952cb..a8f245a19de 100644 --- a/addons/website_hr_recruitment/views/hr_job_views.xml +++ b/addons/website_hr_recruitment/views/hr_job_views.xml @@ -14,8 +14,24 @@ <xpath expr="//div[@name='kanban_boxes']/div/div[1]" position="inside"> <field name="website_url" invisible="1"/> <span> - <a t-attf-href="#{record.website_url.raw_value}">Job Description</a> + <a t-attf-href="#{record.website_url.raw_value}" class="mr-2">Job Description</a> + <field name="is_published" widget='boolean_toggle'/> </span> + </xpath> + </field> + </record> + + <record id="view_hr_job_kanban_referal_extends" model="ir.ui.view"> + <field name="model">hr.job</field> + <field name="name">hr.job.view.kanban</field> + <field name="inherit_id" ref="hr_recruitment.view_hr_job_kanban"/> + <field name="arch" type="xml"> + <xpath expr="//div[hasclass('o_link_trackers')]" position="replace"> + <div class="o_link_trackers col-6"> + <a role="button" name="%(hr_recruitment.action_hr_job_sources)d" type="action" class="btn btn-sm "> + <span title='Link Trackers'><i class='fa fa-lg fa-plus' role="img" aria-label="Link Trackers"/></span> + </a> + </div> </xpath> </field> </record> diff --git a/addons/website_hr_recruitment/views/hr_recruitment_views.xml b/addons/website_hr_recruitment/views/hr_recruitment_views.xml index 6259512546f..72afa514f07 100644 --- a/addons/website_hr_recruitment/views/hr_recruitment_views.xml +++ b/addons/website_hr_recruitment/views/hr_recruitment_views.xml @@ -5,7 +5,7 @@ <field name="model">hr.recruitment.source</field> <field name="inherit_id" ref="hr_recruitment.hr_recruitment_source_tree"/> <field name="arch" type="xml"> - <xpath expr="//field[@name='email']" position="after"> + <xpath expr="//field[@name='email']" position="before"> <field name="url" widget="url"/> </xpath> </field> |
