[IMP] hr_skills*: Add certification and course in employee profile

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) <yti@odoo.com>
This commit is contained in:
jbm-odoo
2019-04-16 14:48:25 +00:00
committed by Yannick Tivisse
parent a54d5eede8
commit 59e6611736
26 changed files with 314 additions and 62 deletions
+2
View File
@@ -3,10 +3,12 @@
<data>
<record id="resume_type_experience" model="hr.resume.line.type">
<field name="name">Experience</field>
<field name="sequence">1</field>
</record>
<record id="resume_type_education" model="hr.resume.line.type">
<field name="name">Education</field>
<field name="sequence">2</field>
</record>
</data>
-21
View File
@@ -20,118 +20,99 @@
<record id="hr_skill_level_a1" model="hr.skill.level">
<field name="name">A1</field>
<field name="level_progress">10</field>
<field name="sequence">5</field>
<field name="skill_type_id" ref="hr_skill_type_lang"/>
</record>
<record id="hr_skill_level_a2" model="hr.skill.level">
<field name="name">A2</field>
<field name="level_progress">40</field>
<field name="sequence">10</field>
<field name="skill_type_id" ref="hr_skill_type_lang"/>
</record>
<record id="hr_skill_level_b1" model="hr.skill.level">
<field name="name">B1</field>
<field name="level_progress">60</field>
<field name="sequence">15</field>
<field name="skill_type_id" ref="hr_skill_type_lang"/>
</record>
<record id="hr_skill_level_b2" model="hr.skill.level">
<field name="name">B2</field>
<field name="level_progress">75</field>
<field name="sequence">20</field>
<field name="skill_type_id" ref="hr_skill_type_lang"/>
</record>
<record id="hr_skill_level_c1" model="hr.skill.level">
<field name="name">C1</field>
<field name="level_progress">85</field>
<field name="sequence">25</field>
<field name="skill_type_id" ref="hr_skill_type_lang"/>
</record>
<record id="hr_skill_level_c2" model="hr.skill.level">
<field name="name">C2</field>
<field name="level_progress">100</field>
<field name="sequence">35</field>
<field name="skill_type_id" ref="hr_skill_type_lang"/>
</record>
<record id="hr_skill_level_beginner" model="hr.skill.level">
<field name="name">Beginner</field>
<field name="level_progress">15</field>
<field name="sequence">1</field>
<field name="skill_type_id" ref="hr_skill_type_dev"/>
</record>
<record id="hr_skill_level_elementary" model="hr.skill.level">
<field name="name">Elementary</field>
<field name="level_progress">25</field>
<field name="sequence">5</field>
<field name="skill_type_id" ref="hr_skill_type_dev"/>
</record>
<record id="hr_skill_level_intermediate" model="hr.skill.level">
<field name="name">Intermediate</field>
<field name="level_progress">50</field>
<field name="sequence">15</field>
<field name="skill_type_id" ref="hr_skill_type_dev"/>
</record>
<record id="hr_skill_level_advanced" model="hr.skill.level">
<field name="name">Advanced</field>
<field name="level_progress">80</field>
<field name="sequence">25</field>
<field name="skill_type_id" ref="hr_skill_type_dev"/>
</record>
<record id="hr_skill_level_expert" model="hr.skill.level">
<field name="name">Expert</field>
<field name="level_progress">100</field>
<field name="sequence">35</field>
<field name="skill_type_id" ref="hr_skill_type_dev"/>
</record>
<record id="hr_skill_level_l1" model="hr.skill.level">
<field name="name">L1</field>
<field name="level_progress">25</field>
<field name="sequence">1</field>
<field name="skill_type_id" ref="hr_skill_type_music"/>
</record>
<record id="hr_skill_level_l2" model="hr.skill.level">
<field name="name">L2</field>
<field name="level_progress">50</field>
<field name="sequence">5</field>
<field name="skill_type_id" ref="hr_skill_type_music"/>
</record>
<record id="hr_skill_level_l3" model="hr.skill.level">
<field name="name">L3</field>
<field name="level_progress">75</field>
<field name="sequence">15</field>
<field name="skill_type_id" ref="hr_skill_type_music"/>
</record>
<record id="hr_skill_level_l4" model="hr.skill.level">
<field name="name">L4</field>
<field name="level_progress">100</field>
<field name="sequence">25</field>
<field name="skill_type_id" ref="hr_skill_type_music"/>
</record>
<record id="hr_skill_level_ml1" model="hr.skill.level">
<field name="name">L1</field>
<field name="level_progress">25</field>
<field name="sequence">1</field>
<field name="skill_type_id" ref="hr_skill_type_marketing"/>
</record>
<record id="hr_skill_level_ml2" model="hr.skill.level">
<field name="name">L2</field>
<field name="level_progress">50</field>
<field name="sequence">5</field>
<field name="skill_type_id" ref="hr_skill_type_marketing"/>
</record>
<record id="hr_skill_level_ml3" model="hr.skill.level">
<field name="name">L3</field>
<field name="level_progress">75</field>
<field name="sequence">15</field>
<field name="skill_type_id" ref="hr_skill_type_marketing"/>
</record>
<record id="hr_skill_level_ml4" model="hr.skill.level">
<field name="name">L4</field>
<field name="level_progress">100</field>
<field name="sequence">25</field>
<field name="skill_type_id" ref="hr_skill_type_marketing"/>
</record>
@@ -279,7 +260,6 @@
<record id="employee_resume_line_admin_4" model="hr.resume.line">
<field name="employee_id" ref="hr.employee_admin"/>
<field name="name">Odoo SA</field>
<field name="sequence">5</field>
<field name="date_start" eval="(datetime.now()+relativedelta(years=-3)).strftime('%Y-11-01')"/>
<field name="line_type_id" ref="resume_type_experience"/>
<field name="description">
@@ -291,7 +271,6 @@
<record id="employee_resume_line_admin_3" model="hr.resume.line">
<field name="employee_id" ref="hr.employee_admin"/>
<field name="name">Burtho Inc.</field>
<field name="sequence">15</field>
<field name="date_start" eval="(datetime.now()+relativedelta(years=-7)).strftime('%Y-09-10')"/>
<field name="date_end" eval="(datetime.now()+relativedelta(years=-3)).strftime('%Y-09-10')"/>
<field name="line_type_id" ref="resume_type_experience"/>
+6 -1
View File
@@ -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)
+2 -1
View File
@@ -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):
+10 -1
View File
@@ -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;
}
}
+10 -12
View File
@@ -103,10 +103,15 @@ var AbstractGroupedOne2ManyRenderer = ListRenderer.extend({
return record.data[self.groupBy].res_id;
});
var groupTitle;
var $body = $('<tbody>');
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 = $('<td/>', {class: 'o_data_cell'});
var $td = $('<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,
@@ -2,25 +2,23 @@
<templates id="template" xml:space="preserve">
<t t-name="hr_resume_data_row">
<tr class="o_data_row" t-att-data-id="id">
<td class="o_data_cell o_list_number o_handle_cell">
<span class="o_row_handle fa fa-arrows o_field_widget ui-sortable-handle" t-att-data-sequence="id"/>
</td>
<td class="o_data_cell container">
<div class="o_resume_line row" t-att-data-id="id">
<div class="o_resume_line_dates col-lg-3">
<div class="row">
<span class="col-6 col-lg-8"><t t-esc="data.date_start"/>-</span>
<span class="col-6 col-lg-6"><t t-esc="data.date_end"/></span>
<t t-if="data.display_type === 'classic'">
<td class="o_data_cell container">
<div class="o_resume_line row" t-att-data-id="id">
<div class="o_resume_line_dates col-lg-3">
<div class="row">
<span class="col-6 col-lg-8"><t t-esc="data.date_start"/>-</span>
<span class="col-6 col-lg-6"><t t-esc="data.date_end"/></span>
</div>
</div>
<div class="o_resume_line_desc col-lg-9">
<h3><t t-esc="data.name"/></h3>
<t t-if="data.description" t-esc="data.description"/>
</div>
</div>
<div class="o_resume_line_desc col-lg-9">
<h3><t t-esc="data.name"/></h3>
<t t-if="data.description" t-esc="data.description"/>
</div>
</div>
</td>
</td>
</t>
</tr>
</t>
@@ -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) {
'<field name="description"/>' +
'<field name="date_start"/>' +
'<field name="date_end"/>' +
'<field name="sequence"/>' +
'<field name="display_type"/>' +
'</tree>' +
'</field>' +
'</form>',
@@ -193,7 +194,6 @@ odoo.define('hr_skills.field_one_to_many_group_tests', function (require) {
'<field name="description"/>' +
'<field name="date_start"/>' +
'<field name="date_end"/>' +
'<field name="sequence"/>' +
'</tree>' +
'</field>' +
'</form>',
@@ -248,7 +248,6 @@ odoo.define('hr_skills.field_one_to_many_group_tests', function (require) {
'<field name="description"/>' +
'<field name="date_start"/>' +
'<field name="date_end"/>' +
'<field name="sequence"/>' +
'</tree>' +
'</field>' +
'</form>',
+3 -4
View File
@@ -37,7 +37,7 @@
<group>
<group>
<field name="line_type_id"/>
<field name="sequence" groups="base.group_no_one"/>
<field name="display_type" invisible="1"/>
</group>
<group>
<field name="date_start" required="True"/>
@@ -65,10 +65,10 @@
<tree>
<field name="line_type_id"/>
<field name="name"/>
<field name="sequence" widget="handle"/>
<field name="description"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="display_type" invisible="1"/>
</tree>
</field>
</div>
@@ -105,10 +105,10 @@
<tree>
<field name="line_type_id"/>
<field name="name"/>
<field name="sequence" widget="handle"/>
<field name="description"/>
<field name="date_start"/>
<field name="date_end"/>
<field name="display_type" invisible="1"/>
</tree>
</field>
</div>
@@ -158,7 +158,6 @@
<field name="model">hr.skill.level</field>
<field name="arch" type="xml">
<tree string="Skill Levels">
<field name="sequence" widget="handle"/>
<field name="name"/>
<field name="level_progress" widget="progressbar"/>
</tree>
+4
View File
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
+25
View File
@@ -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,
}
@@ -0,0 +1,10 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<data>
<record id="resume_type_training" model="hr.resume.line.type">
<field name="name">Internal Training</field>
<field name="sequence">26</field>
</record>
</data>
</odoo>
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import slide_channel
@@ -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)
@@ -0,0 +1,6 @@
.o_resume_line {
.o_resume_line_icon.icon_circle {
color: $o-enterprise-primary-color;
vertical-align: middle;
}
}
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-extend="hr_resume_data_row">
<t t-jquery="tr.o_data_row" t-operation="append">
<t t-if="data.display_type === 'course'">
<td class="o_data_cell container">
<div class="o_resume_line row" t-att-data-id="id">
<div class="o_resume_line_dates col-lg-3">
<span><t t-esc="data.date_start"/></span>
</div>
<div class="o_resume_line_desc col-lg-8">
<h3><t t-esc="data.name"/></h3>
<t t-if="data.description" t-esc="data.description"/>
</div>
<div class="o_resume_line_icon icon_circle col-lg-1">
<i class="fa fa-check-circle fa-2x"></i>
</div>
</div>
</td>
</t>
</t>
</t>
</templates>
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_backend" name="hr_skills_assets_backend" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<link rel="stylesheet" type="text/scss" href="/hr_skills_slides/static/src/scss/hr_skills.scss"/>
</xpath>
</template>
<record id="resume_slides_line_view_form" model="ir.ui.view">
<field name="name">hr.resume.line.form</field>
<field name="model">hr.resume.line</field>
<field name="inherit_id" ref="hr_skills.resume_line_view_form"/>
<field eval="20" name="priority"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='line_type_id']" position="after">
<field name="channel_id" attrs="{'invisible': [('display_type', '!=', 'course')]}"/>
</xpath>
</field>
</record>
</odoo>
+4
View File
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import models
+25
View File
@@ -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,
}
@@ -0,0 +1,10 @@
<?xml version='1.0' encoding='utf-8'?>
<odoo>
<data>
<record id="resume_type_certification" model="hr.resume.line.type">
<field name="name">Internal Certification</field>
<field name="sequence">25</field>
</record>
</data>
</odoo>
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import survey_user
@@ -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)
@@ -0,0 +1,5 @@
.o_resume_line {
.o_resume_line_icon.icon_trophy {
color: theme-color('warning');
}
}
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">
<t t-extend="hr_resume_data_row">
<t t-jquery="tr.o_data_row" t-operation="append">
<t t-if="data.display_type === 'certification'">
<td class="o_data_cell container">
<div class="o_resume_line row" t-att-data-id="id">
<div class="o_resume_line_dates col-lg-3">
<span><t t-esc="data.date_start"/></span>
</div>
<div class="o_resume_line_desc col-lg-8">
<h3><t t-esc="data.name"/></h3>
<t t-if="data.description" t-esc="data.description"/>
</div>
<div class="o_resume_line_icon icon_trophy col-lg-1">
<i class="fa fa-trophy fa-2x"></i>
</div>
</div>
</td>
</t>
</t>
</t>
</templates>
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="assets_backend" name="hr_skills_survey_assets_backend" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<link rel="stylesheet" type="text/scss" href="/hr_skills_survey/static/src/scss/hr_skills.scss"/>
</xpath>
</template>
<record id="resume_survey_line_view_form" model="ir.ui.view">
<field name="name">hr.resume.line.form</field>
<field name="model">hr.resume.line</field>
<field name="inherit_id" ref="hr_skills.resume_line_view_form"/>
<field eval="20" name="priority"/>
<field name="arch" type="xml">
<xpath expr="//field[@name='line_type_id']" position="after">
<field name="survey_id" attrs="{'invisible': [('display_type', '!=', 'certification')]}"/>
</xpath>
</field>
</record>
</odoo>
@@ -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. """