From 59e66117361789f0ee0e915ab435bb987cf99d87 Mon Sep 17 00:00:00 2001 From: jbm-odoo Date: Fri, 8 Mar 2019 15:21:18 +0000 Subject: [PATCH] [IMP] hr_skills*: Add certification and course in employee profile MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When a employee succeed a course or a certification, a new line will be added in resumé of employee profile. + [FIX] hr_skills: remove sequence to sort resumé Actually, sorting a resumé doesn't work because we add new line for title in the array. With this commit, all sequence are removed. The resumé is sorted by date and skills are sorted by level. closes odoo/odoo#31764 Signed-off-by: Yannick Tivisse (yti) --- addons/hr_skills/data/hr_resume_data.xml | 2 + addons/hr_skills/data/hr_resume_demo.xml | 21 ---------- addons/hr_skills/models/hr_resume.py | 7 +++- addons/hr_skills/models/hr_skills.py | 3 +- .../hr_skills/static/src/css/hr_skills.scss | 11 ++++- .../hr_skills/static/src/js/resume_widget.js | 22 +++++----- .../static/src/xml/resume_templates.xml | 30 +++++++------- addons/hr_skills/static/tests/widget_tests.js | 11 +++-- addons/hr_skills/views/hr_views.xml | 7 ++-- addons/hr_skills_slides/__init__.py | 4 ++ addons/hr_skills_slides/__manifest__.py | 25 ++++++++++++ .../hr_skills_slides/data/hr_resume_data.xml | 10 +++++ addons/hr_skills_slides/models/__init__.py | 4 ++ .../hr_skills_slides/models/slide_channel.py | 33 +++++++++++++++ .../static/src/scss/hr_skills.scss | 6 +++ .../static/src/xml/resume_templates.xml | 24 +++++++++++ .../hr_skills_slides/views/hr_templates.xml | 20 ++++++++++ addons/hr_skills_survey/__init__.py | 4 ++ addons/hr_skills_survey/__manifest__.py | 25 ++++++++++++ .../hr_skills_survey/data/hr_resume_data.xml | 10 +++++ addons/hr_skills_survey/models/__init__.py | 4 ++ addons/hr_skills_survey/models/survey_user.py | 40 +++++++++++++++++++ .../static/src/scss/hr_skills.scss | 5 +++ .../static/src/xml/resume_templates.xml | 25 ++++++++++++ .../hr_skills_survey/views/hr_templates.xml | 20 ++++++++++ addons/website_slides/models/slide_channel.py | 3 ++ 26 files changed, 314 insertions(+), 62 deletions(-) create mode 100644 addons/hr_skills_slides/__init__.py create mode 100644 addons/hr_skills_slides/__manifest__.py create mode 100644 addons/hr_skills_slides/data/hr_resume_data.xml create mode 100644 addons/hr_skills_slides/models/__init__.py create mode 100644 addons/hr_skills_slides/models/slide_channel.py create mode 100644 addons/hr_skills_slides/static/src/scss/hr_skills.scss create mode 100644 addons/hr_skills_slides/static/src/xml/resume_templates.xml create mode 100644 addons/hr_skills_slides/views/hr_templates.xml create mode 100644 addons/hr_skills_survey/__init__.py create mode 100644 addons/hr_skills_survey/__manifest__.py create mode 100644 addons/hr_skills_survey/data/hr_resume_data.xml create mode 100644 addons/hr_skills_survey/models/__init__.py create mode 100644 addons/hr_skills_survey/models/survey_user.py create mode 100644 addons/hr_skills_survey/static/src/scss/hr_skills.scss create mode 100644 addons/hr_skills_survey/static/src/xml/resume_templates.xml create mode 100644 addons/hr_skills_survey/views/hr_templates.xml diff --git a/addons/hr_skills/data/hr_resume_data.xml b/addons/hr_skills/data/hr_resume_data.xml index b5fbde4443f..8c948d35ac9 100644 --- a/addons/hr_skills/data/hr_resume_data.xml +++ b/addons/hr_skills/data/hr_resume_data.xml @@ -3,10 +3,12 @@ Experience + 1 Education + 2 diff --git a/addons/hr_skills/data/hr_resume_demo.xml b/addons/hr_skills/data/hr_resume_demo.xml index 79cd1a4ea8c..3f431865491 100644 --- a/addons/hr_skills/data/hr_resume_demo.xml +++ b/addons/hr_skills/data/hr_resume_demo.xml @@ -20,118 +20,99 @@ A1 10 - 5 A2 40 - 10 B1 60 - 15 B2 75 - 20 C1 85 - 25 C2 100 - 35 Beginner 15 - 1 Elementary 25 - 5 Intermediate 50 - 15 Advanced 80 - 25 Expert 100 - 35 L1 25 - 1 L2 50 - 5 L3 75 - 15 L4 100 - 25 L1 25 - 1 L2 50 - 5 L3 75 - 15 L4 100 - 25 @@ -279,7 +260,6 @@ Odoo SA - 5 @@ -291,7 +271,6 @@ Burtho Inc. - 15 diff --git a/addons/hr_skills/models/hr_resume.py b/addons/hr_skills/models/hr_resume.py index bfea9306cee..7725a5c05ac 100644 --- a/addons/hr_skills/models/hr_resume.py +++ b/addons/hr_skills/models/hr_resume.py @@ -30,6 +30,7 @@ class Employee(models.Model): class ResumeLine(models.Model): _name = 'hr.resume.line' _description = "Resumé line of an employee" + _order = "line_type_id, date_end desc, date_start desc" employee_id = fields.Many2one('hr.employee', required=True, ondelete='cascade') name = fields.Char(required=True) @@ -37,7 +38,9 @@ class ResumeLine(models.Model): date_end = fields.Date() description = fields.Text(string="Description") line_type_id = fields.Many2one('hr.resume.line.type', string="Type") - sequence = fields.Integer(default=100) + + # Used to apply specific template on a line + display_type = fields.Selection([('classic', 'Classic')], string="Display Type", default='classic') _sql_constraints = [ ('date_check', "CHECK ((date_start <= date_end OR date_end = NULL))", "The start date must be anterior to the end date."), @@ -47,5 +50,7 @@ class ResumeLine(models.Model): class ResumeLineType(models.Model): _name = 'hr.resume.line.type' _description = "Type of a resumé line" + _order = "sequence" name = fields.Char(required=True) + sequence = fields.Integer('Sequence', default=10) diff --git a/addons/hr_skills/models/hr_skills.py b/addons/hr_skills/models/hr_skills.py index 5b75a5ac146..4eeb950a71b 100644 --- a/addons/hr_skills/models/hr_skills.py +++ b/addons/hr_skills/models/hr_skills.py @@ -17,6 +17,7 @@ class EmployeeSkill(models.Model): _name = 'hr.employee.skill' _description = "Skill level for an employee" _rec_name = 'skill_id' + _order = "skill_level_id" employee_id = fields.Many2one('hr.employee', required=True, ondelete='cascade') skill_id = fields.Many2one('hr.skill', required=True) @@ -44,11 +45,11 @@ class EmployeeSkill(models.Model): class SkillLevel(models.Model): _name = 'hr.skill.level' _description = "Skill Level" + _order = "level_progress desc" skill_type_id = fields.Many2one('hr.skill.type') name = fields.Char(required=True) level_progress = fields.Integer(string="Progress", help="Progress from zero knowledge (0%) to fully mastered (100%).") - sequence = fields.Integer(default=100) class SkillType(models.Model): diff --git a/addons/hr_skills/static/src/css/hr_skills.scss b/addons/hr_skills/static/src/css/hr_skills.scss index cb1a7072922..439b082cdcf 100644 --- a/addons/hr_skills/static/src/css/hr_skills.scss +++ b/addons/hr_skills/static/src/css/hr_skills.scss @@ -1,4 +1,9 @@ .o_form_sheet { + .o_resume_table th, + .o_resume_table td { + border: none; + } + .o_resume_line { width: 100%; } @@ -12,10 +17,14 @@ } td.o_skill_cell { - width: 33%; + white-space: normal !important; } .o_group_resume tbody tr.o_resume_group_header th { font-weight: normal; } + + .o_resume_line_desc { + white-space: normal; + } } diff --git a/addons/hr_skills/static/src/js/resume_widget.js b/addons/hr_skills/static/src/js/resume_widget.js index 7bb2023b76f..10cbfbfc874 100644 --- a/addons/hr_skills/static/src/js/resume_widget.js +++ b/addons/hr_skills/static/src/js/resume_widget.js @@ -103,10 +103,15 @@ var AbstractGroupedOne2ManyRenderer = ListRenderer.extend({ return record.data[self.groupBy].res_id; }); + var groupTitle; var $body = $(''); for (var key in grouped_by) { var group = grouped_by[key]; - var groupTitle = group[0].data[self.groupBy].data.display_name; + if (key === 'undefined') { + groupTitle = _t("Other"); + } else { + groupTitle = group[0].data[self.groupBy].data.display_name; + } var $title_row = $(self._renderGroupRow(groupTitle)); $body.append($title_row); @@ -148,21 +153,14 @@ var ResumeLineRenderer = AbstractGroupedOne2ManyRenderer.extend({ _getCreateLineContext: function (group) { var ctx = this._super(group); - return group ? _.extend({ default_line_type_id: group[0].data[this.groupBy].data.id }, ctx) : ctx; + return group ? _.extend({default_line_type_id: group[0].data[this.groupBy] && group[0].data[this.groupBy].data.id || ""}, ctx) : ctx; }, _render: function () { var self = this; return this._super().then(function () { - // Allow to sort records - self.$el.find('.o_list_view').sortable({ - axis: 'y', - items: '.o_data_row', - helper: 'clone', - handle: '.o_row_handle', - stop: self._resequence.bind(self), - }); - self.$el.find('table').removeClass('table table-striped o_list_view_ungrouped'); + self.$el.find('table').removeClass('table-striped o_list_view_ungrouped'); + self.$el.find('table').addClass('o_resume_table'); }); }, }); @@ -176,7 +174,7 @@ var SkillsRenderer = AbstractGroupedOne2ManyRenderer.extend({ _renderRow: function (record) { var $row = this._super(record); // Add progress bar widget at the end of rows - var $td = $('', {class: 'o_data_cell'}); + var $td = $('', {class: 'o_data_cell o_skill_cell'}); var progress = new FieldProgressBar(this, 'level_progress', record, { current_value: record.data.level_progress, attrs: this.arch.attrs, diff --git a/addons/hr_skills/static/src/xml/resume_templates.xml b/addons/hr_skills/static/src/xml/resume_templates.xml index 89d7352f464..7da6ea3434a 100644 --- a/addons/hr_skills/static/src/xml/resume_templates.xml +++ b/addons/hr_skills/static/src/xml/resume_templates.xml @@ -2,25 +2,23 @@ - - - - - -
-
-
- - - + + +
+
+
+ - + +
+
+
+

+
-
-

- -
-
- + + diff --git a/addons/hr_skills/static/tests/widget_tests.js b/addons/hr_skills/static/tests/widget_tests.js index 3bee4c4ee29..00cdc648401 100644 --- a/addons/hr_skills/static/tests/widget_tests.js +++ b/addons/hr_skills/static/tests/widget_tests.js @@ -82,21 +82,21 @@ odoo.define('hr_skills.field_one_to_many_group_tests', function (require) { fields: { name: { string: "Name", type: "char" }, line_type_id: { string: "Type", relation: 'line_type', type: "many2one" }, - sequence: { string: "Sequence", type: "int", default:10 }, description: { string: "Description", type: "text" }, date_start: { string: "Date start", type: "date" }, date_end: { string: "Date end", type: "date" }, trululu: { string: "Trululu", type: "many2one", relation: 'partner' }, + display_type: { string: "display type", type: "selection"}, }, records: [{ id: 37, name: "ULB", line_type_id: 50, - sequence: 5, date_start: "2017-01-25", date_end: "2019-01-25", description: 'Hello', trululu: 1, + display_type: 'classic', }, { id: 38, name: "UCL", @@ -105,14 +105,15 @@ odoo.define('hr_skills.field_one_to_many_group_tests', function (require) { date_end: "2014-01-25", description: 'World', trululu: 1, + display_type: 'classic', }, { id: 39, name: "KUL", line_type_id: 51, - sequence: 15, date_start: "2008-01-25", description: 'Hi', trululu: 1, + display_type: 'classic', }], onchanges: {}, }, @@ -145,7 +146,7 @@ odoo.define('hr_skills.field_one_to_many_group_tests', function (require) { '' + '' + '' + - '' + + '' + '' + '' + '', @@ -193,7 +194,6 @@ odoo.define('hr_skills.field_one_to_many_group_tests', function (require) { '' + '' + '' + - '' + '' + '' + '', @@ -248,7 +248,6 @@ odoo.define('hr_skills.field_one_to_many_group_tests', function (require) { '' + '' + '' + - '' + '' + '' + '', diff --git a/addons/hr_skills/views/hr_views.xml b/addons/hr_skills/views/hr_views.xml index fd92c8bd588..98f2a73e59e 100644 --- a/addons/hr_skills/views/hr_views.xml +++ b/addons/hr_skills/views/hr_views.xml @@ -37,7 +37,7 @@ - + @@ -65,10 +65,10 @@ - +
@@ -105,10 +105,10 @@ - +
@@ -158,7 +158,6 @@ hr.skill.level - diff --git a/addons/hr_skills_slides/__init__.py b/addons/hr_skills_slides/__init__.py new file mode 100644 index 00000000000..dc5e6b693d1 --- /dev/null +++ b/addons/hr_skills_slides/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/addons/hr_skills_slides/__manifest__.py b/addons/hr_skills_slides/__manifest__.py new file mode 100644 index 00000000000..d85aa5829b9 --- /dev/null +++ b/addons/hr_skills_slides/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Skills e-learning', + 'category': 'Hidden', + 'version': '1.0', + 'summary': 'Add completed courses to resumé of your employees', + 'description': + """ +E-learning and Skills for HR +============================ + +This module add completed courses to resumé for employees. + """, + 'depends': ['hr_skills', 'website_slides'], + 'data': [ + 'views/hr_templates.xml', + 'data/hr_resume_data.xml', + ], + 'qweb': [ + 'static/src/xml/resume_templates.xml', + ], + 'auto_install': True, +} diff --git a/addons/hr_skills_slides/data/hr_resume_data.xml b/addons/hr_skills_slides/data/hr_resume_data.xml new file mode 100644 index 00000000000..92edc9db157 --- /dev/null +++ b/addons/hr_skills_slides/data/hr_resume_data.xml @@ -0,0 +1,10 @@ + + + + + Internal Training + 26 + + + + diff --git a/addons/hr_skills_slides/models/__init__.py b/addons/hr_skills_slides/models/__init__.py new file mode 100644 index 00000000000..c9c3eb273a8 --- /dev/null +++ b/addons/hr_skills_slides/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import slide_channel diff --git a/addons/hr_skills_slides/models/slide_channel.py b/addons/hr_skills_slides/models/slide_channel.py new file mode 100644 index 00000000000..f6053abdd14 --- /dev/null +++ b/addons/hr_skills_slides/models/slide_channel.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models + + +class ChannelUsersRelation(models.Model): + _inherit = 'slide.channel.partner' + + def _post_completion_hook(self): + partner_has_completed = {channel_partner.partner_id.id: channel_partner.channel_id for channel_partner in self} + employees = self.env['hr.employee'].sudo().search([('user_id.partner_id', 'in', list(partner_has_completed.keys()))]) + for employee in employees: + line_type = self.env.ref('hr_skills_slides.resume_type_training', raise_if_not_found=False) + channel = partner_has_completed[employee.user_id.partner_id.id] + self.env['hr.resume.line'].create({ + 'employee_id': employee.id, + 'name': channel.name, + 'date_start': fields.Date.today(), + 'date_end': fields.Date.today(), + 'description': channel.description, + 'line_type_id': line_type and line_type.id, + 'display_type': 'course', + 'channel_id': channel.id + }) + return super()._post_completion_hook() + + +class ResumeLine(models.Model): + _inherit = 'hr.resume.line' + + display_type = fields.Selection(selection_add=[('course', 'Course')]) + channel_id = fields.Many2one('slide.channel', string="Course", readonly=True) diff --git a/addons/hr_skills_slides/static/src/scss/hr_skills.scss b/addons/hr_skills_slides/static/src/scss/hr_skills.scss new file mode 100644 index 00000000000..40edfefed6e --- /dev/null +++ b/addons/hr_skills_slides/static/src/scss/hr_skills.scss @@ -0,0 +1,6 @@ +.o_resume_line { + .o_resume_line_icon.icon_circle { + color: $o-enterprise-primary-color; + vertical-align: middle; + } +} diff --git a/addons/hr_skills_slides/static/src/xml/resume_templates.xml b/addons/hr_skills_slides/static/src/xml/resume_templates.xml new file mode 100644 index 00000000000..bcad8b1284e --- /dev/null +++ b/addons/hr_skills_slides/static/src/xml/resume_templates.xml @@ -0,0 +1,24 @@ + + + + + + + +
+
+ +
+
+

+ +
+
+ +
+
+ +
+
+
+
diff --git a/addons/hr_skills_slides/views/hr_templates.xml b/addons/hr_skills_slides/views/hr_templates.xml new file mode 100644 index 00000000000..be9ae969d56 --- /dev/null +++ b/addons/hr_skills_slides/views/hr_templates.xml @@ -0,0 +1,20 @@ + + + + + + hr.resume.line.form + hr.resume.line + + + + + + + + + diff --git a/addons/hr_skills_survey/__init__.py b/addons/hr_skills_survey/__init__.py new file mode 100644 index 00000000000..dc5e6b693d1 --- /dev/null +++ b/addons/hr_skills_survey/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import models diff --git a/addons/hr_skills_survey/__manifest__.py b/addons/hr_skills_survey/__manifest__.py new file mode 100644 index 00000000000..339c0b65a14 --- /dev/null +++ b/addons/hr_skills_survey/__manifest__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +{ + 'name': 'Skills Certification', + 'category': 'Hidden', + 'version': '1.0', + 'summary': 'Add certification to resumé of your employees', + 'description': + """ +Certification and Skills for HR +=============================== + +This module add certification to resumé for employees. + """, + 'depends': ['hr_skills', 'survey'], + 'data': [ + 'views/hr_templates.xml', + 'data/hr_resume_data.xml', + ], + 'qweb': [ + 'static/src/xml/resume_templates.xml', + ], + 'auto_install': True, +} diff --git a/addons/hr_skills_survey/data/hr_resume_data.xml b/addons/hr_skills_survey/data/hr_resume_data.xml new file mode 100644 index 00000000000..8a53cbab253 --- /dev/null +++ b/addons/hr_skills_survey/data/hr_resume_data.xml @@ -0,0 +1,10 @@ + + + + + Internal Certification + 25 + + + + diff --git a/addons/hr_skills_survey/models/__init__.py b/addons/hr_skills_survey/models/__init__.py new file mode 100644 index 00000000000..25325ac6482 --- /dev/null +++ b/addons/hr_skills_survey/models/__init__.py @@ -0,0 +1,4 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from . import survey_user diff --git a/addons/hr_skills_survey/models/survey_user.py b/addons/hr_skills_survey/models/survey_user.py new file mode 100644 index 00000000000..43e85b40cca --- /dev/null +++ b/addons/hr_skills_survey/models/survey_user.py @@ -0,0 +1,40 @@ +# -*- coding: utf-8 -*- +# Part of Odoo. See LICENSE file for full copyright and licensing details. + +from odoo import fields, models +from odoo.tools import html2plaintext + + +class SurveyUserInput(models.Model): + _inherit = 'survey.user_input' + + def _send_certification(self): + """ Will add certification to employee's resumé if + - The survey is a certification + - The user is linked to an employee + - The user succeeded the test + At the end, super is call to send by mail""" + certificate_user_inputs = self.filtered(lambda user_input: user_input.survey_id.certificate and user_input.quizz_passed) + partner_has_completed = {user_input.partner_id.id: user_input.survey_id for user_input in certificate_user_inputs} + employees = self.env['hr.employee'].sudo().search([('user_id.partner_id', 'in', certificate_user_inputs.mapped('partner_id').ids)]) + for employee in employees: + line_type = self.env.ref('hr_skills_survey.resume_type_certification', raise_if_not_found=False) + survey = partner_has_completed.get(employee.user_id.partner_id.id) + self.env['hr.resume.line'].create({ + 'employee_id': employee.id, + 'name': survey.title, + 'date_start': fields.Date.today(), + 'date_end': fields.Date.today(), + 'description': html2plaintext(survey.description), + 'line_type_id': line_type and line_type.id, + 'display_type': 'certification', + 'survey_id': survey.id + }) + return super(SurveyUserInput, self)._send_certification() + + +class ResumeLine(models.Model): + _inherit = 'hr.resume.line' + + display_type = fields.Selection(selection_add=[('certification', 'Certification')]) + survey_id = fields.Many2one('survey.survey', string='Certification', readonly=True) diff --git a/addons/hr_skills_survey/static/src/scss/hr_skills.scss b/addons/hr_skills_survey/static/src/scss/hr_skills.scss new file mode 100644 index 00000000000..864fb11dd43 --- /dev/null +++ b/addons/hr_skills_survey/static/src/scss/hr_skills.scss @@ -0,0 +1,5 @@ +.o_resume_line { + .o_resume_line_icon.icon_trophy { + color: theme-color('warning'); + } +} diff --git a/addons/hr_skills_survey/static/src/xml/resume_templates.xml b/addons/hr_skills_survey/static/src/xml/resume_templates.xml new file mode 100644 index 00000000000..2734f5ba6d1 --- /dev/null +++ b/addons/hr_skills_survey/static/src/xml/resume_templates.xml @@ -0,0 +1,25 @@ + + + + + + + +
+
+ +
+
+

+ +
+
+ +
+
+ +
+
+
+ +
diff --git a/addons/hr_skills_survey/views/hr_templates.xml b/addons/hr_skills_survey/views/hr_templates.xml new file mode 100644 index 00000000000..365a7240e52 --- /dev/null +++ b/addons/hr_skills_survey/views/hr_templates.xml @@ -0,0 +1,20 @@ + + + + + + hr.resume.line.form + hr.resume.line + + + + + + + + + diff --git a/addons/website_slides/models/slide_channel.py b/addons/website_slides/models/slide_channel.py index f504ecc03fd..c68961aace1 100644 --- a/addons/website_slides/models/slide_channel.py +++ b/addons/website_slides/models/slide_channel.py @@ -60,6 +60,7 @@ class ChannelUsersRelation(models.Model): result = super(ChannelUsersRelation, (self - to_complete))._write(values) completion_values = dict(values, completed=True) super(ChannelUsersRelation, to_complete)._write(completion_values) + to_complete._post_completion_hook() else: result = super(ChannelUsersRelation, self)._write(values) @@ -69,6 +70,8 @@ class ChannelUsersRelation(models.Model): users.add_karma(partner_karma[user.partner_id.id]) return result + def _post_completion_hook(self): + pass class Channel(models.Model): """ A channel is a container of slides. """