[ADD]Serpent CS web_one2many_kanban
This commit is contained in:
parent
1e071705aa
commit
e40f5a78a8
@ -0,0 +1,2 @@
|
||||
eclipse.preferences.version=1
|
||||
encoding/__openerp__.py=utf-8
|
22
web_one2many_kanban/__init__.py
Normal file
22
web_one2many_kanban/__init__.py
Normal file
@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2011-2014 Serpent Consulting Services Pvt. Ltd.
|
||||
# (<http://serpentcs.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
44
web_one2many_kanban/__openerp__.py
Normal file
44
web_one2many_kanban/__openerp__.py
Normal file
@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2011-2014 Serpent Consulting Services Pvt. Ltd.
|
||||
# (<http://serpentcs.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
{
|
||||
'name': 'Web one2many Kanban',
|
||||
'version': '1.0.1',
|
||||
'sequence': 6,
|
||||
'author': 'Serpent Consulting Services Pvt. Ltd.',
|
||||
'description' : """
|
||||
You need to define o2m field in kanban view definition and use
|
||||
for loop to display fields like:
|
||||
|
||||
<t t-foreach="record.o2mfield.raw_value" t-as='o'>
|
||||
<t t-esc="o.name">
|
||||
</t>
|
||||
""",
|
||||
'installable': True,
|
||||
'application': True,
|
||||
'data':[
|
||||
'view/templates.xml',
|
||||
],
|
||||
'depends': ['web'],
|
||||
'auto_install': False,
|
||||
}
|
BIN
web_one2many_kanban/static/description/icon.png
Normal file
BIN
web_one2many_kanban/static/description/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 16 KiB |
55
web_one2many_kanban/static/description/index.html
Normal file
55
web_one2many_kanban/static/description/index.html
Normal file
@ -0,0 +1,55 @@
|
||||
<html>
|
||||
<body>
|
||||
<section class="oe_container oe_dark">
|
||||
<div class="oe_row">
|
||||
<div class="oe_row">
|
||||
<h2 class="oe_slogan">Web one2many Kanban</h2>
|
||||
</div>
|
||||
<div style="margin: 16px 8%;">
|
||||
<p class='oe_mt32'>
|
||||
This module is developed to extend the functionality of kanban view. There are certain occasions where you need to display one2many records in kanban view. This module fills the gap at certain extent by allowing to display one2many records in kanban view.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section class='oe_container oe_dark'>
|
||||
<div class='oe_row'>
|
||||
<div class="oe_demo oe_picture oe_screenshot" style="height:400px;">
|
||||
<img src="screen_shot_1.png">
|
||||
</div>
|
||||
<div style="margin: 16px 8%;">
|
||||
<p class='oe_mt32'>
|
||||
This is the one2many records which is displayed in form view.
|
||||
</p>
|
||||
<p>
|
||||
You need to define o2m field in kanban view definition and use
|
||||
for loop(same way we use in qweb) to display fields in kanban view.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class='oe_container oe_dark'>
|
||||
<div class='oe_row'>
|
||||
<div style="margin: 16px 8%;">
|
||||
<p class='oe_mt32'>
|
||||
After installing this module kanban view with one2many record will be display like :-
|
||||
</p>
|
||||
</div>
|
||||
<div class="oe_demo oe_picture oe_screenshot">
|
||||
<img src="screen_shot_2.png">
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<div align='center'>
|
||||
<a href='http://www.serpentcs.com/serpentcs-serpentcs-offers-for-odoo-services' target='_blank'>
|
||||
<img width='120' src="http://www.serpentcs.com/wp-content/uploads/2015/12/special-offers.png">
|
||||
</a>
|
||||
<a href='http://www.serpentcs.com/serpentcs-serpentcs-offers-for-odoo-services' target='_blank'>
|
||||
SerpentCS Anniversary Offers for Odoo Services!
|
||||
</a>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
BIN
web_one2many_kanban/static/description/screen_shot_1.png
Normal file
BIN
web_one2many_kanban/static/description/screen_shot_1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
BIN
web_one2many_kanban/static/description/screen_shot_2.png
Normal file
BIN
web_one2many_kanban/static/description/screen_shot_2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 44 KiB |
302
web_one2many_kanban/static/src/js/web_one2many_kanban.js
Normal file
302
web_one2many_kanban/static/src/js/web_one2many_kanban.js
Normal file
@ -0,0 +1,302 @@
|
||||
openerp.web_one2many_kanban = function(instance) {
|
||||
var QWeb = instance.web.qweb;
|
||||
var _t = instance.web._t;
|
||||
|
||||
/*Kanban view For one2many*/
|
||||
|
||||
instance.web_kanban.KanbanView.include({
|
||||
|
||||
add_qweb_template: function() {
|
||||
this.same_field = []
|
||||
for (var i=0, ii=this.fields_view.arch.children.length; i < ii; i++) {
|
||||
var child = this.fields_view.arch.children[i];
|
||||
if (child.tag === "templates") {
|
||||
this.transform_qweb_template(child);
|
||||
this.qweb.add_template(instance.web.json_node_to_xml(child));
|
||||
break;
|
||||
} else if (child.tag === 'field') {
|
||||
this.extract_aggregates(child);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
transform_qweb_template: function(node) {
|
||||
var qweb_add_if = function(node, condition) {
|
||||
if (node.attrs[QWeb.prefix + '-if']) {
|
||||
condition = _.str.sprintf("(%s) and (%s)", node.attrs[QWeb.prefix + '-if'], condition);
|
||||
}
|
||||
node.attrs[QWeb.prefix + '-if'] = condition;
|
||||
};
|
||||
// Process modifiers
|
||||
if (node.tag && node.attrs.modifiers) {
|
||||
var modifiers = JSON.parse(node.attrs.modifiers || '{}');
|
||||
if (modifiers.invisible) {
|
||||
qweb_add_if(node, _.str.sprintf("!kanban_compute_domain(%s)", JSON.stringify(modifiers.invisible)));
|
||||
}
|
||||
}
|
||||
switch (node.tag) {
|
||||
case 'div':
|
||||
case 'tr':
|
||||
case 'table':
|
||||
case 'td':
|
||||
case 'span':
|
||||
case 't':
|
||||
var self =this
|
||||
self.dataset.o2m_field = {}
|
||||
if(node.attrs['t-foreach'] != undefined){
|
||||
var field_name = node.attrs['t-foreach'].split('.')[1]
|
||||
if(field_name != undefined){
|
||||
self.field_details = this.fields_view.fields[field_name];
|
||||
if(self.field_details.type == 'one2many' && (self.field_details.related != undefined || self.field_details.relation_field != undefined) && self.same_field.indexOf(field_name) == -1){
|
||||
self.same_field.push(field_name)
|
||||
var model = self.field_details.relation
|
||||
self.o2m_dataset = new instance.web.DataSetSearch(self,model, {}, []);
|
||||
self.o2m_dataset.call('fields_get').done(function(data) {
|
||||
var fields=[]
|
||||
_.each(data, function(field_def, field_name) {
|
||||
if(field_def.type != 'many2many'){
|
||||
fields.push(field_name)
|
||||
}
|
||||
});
|
||||
self.dataset.o2m_field[field_name] = {'field_name':field_name,'model':model,'fields':fields}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'field':
|
||||
var ftype = this.fields_view.fields[node.attrs.name].type;
|
||||
ftype = node.attrs.widget ? node.attrs.widget : ftype;
|
||||
if (ftype === 'many2many') {
|
||||
if (_.indexOf(this.many2manys, node.attrs.name) < 0) {
|
||||
this.many2manys.push(node.attrs.name);
|
||||
}
|
||||
node.tag = 'div';
|
||||
node.attrs['class'] = (node.attrs['class'] || '') + ' oe_form_field oe_tags';
|
||||
} else if (instance.web_kanban.fields_registry.contains(ftype)) {
|
||||
// do nothing, the kanban record will handle it
|
||||
} else {
|
||||
node.tag = QWeb.prefix;
|
||||
node.attrs[QWeb.prefix + '-esc'] = 'record.' + node.attrs['name'] + '.value';
|
||||
}
|
||||
break;
|
||||
case 'button':
|
||||
case 'a':
|
||||
var type = node.attrs.type || '';
|
||||
if (_.indexOf('action,object,edit,open,delete'.split(','), type) !== -1) {
|
||||
_.each(node.attrs, function(v, k) {
|
||||
if (_.indexOf('icon,type,name,args,string,context,states,kanban_states'.split(','), k) != -1) {
|
||||
node.attrs['data-' + k] = v;
|
||||
delete(node.attrs[k]);
|
||||
}
|
||||
});
|
||||
if (node.attrs['data-string']) {
|
||||
node.attrs.title = node.attrs['data-string'];
|
||||
}
|
||||
if (node.attrs['data-icon']) {
|
||||
node.children = [{
|
||||
tag: 'img',
|
||||
attrs: {
|
||||
src: instance.session.prefix + '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png',
|
||||
width: '16',
|
||||
height: '16'
|
||||
}
|
||||
}];
|
||||
}
|
||||
if (node.tag == 'a') {
|
||||
node.attrs.href = '#';
|
||||
} else {
|
||||
node.attrs.type = 'button';
|
||||
}
|
||||
node.attrs['class'] = (node.attrs['class'] || '') + ' oe_kanban_action oe_kanban_action_' + node.tag;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (node.children) {
|
||||
for (var i = 0, ii = node.children.length; i < ii; i++) {
|
||||
this.transform_qweb_template(node.children[i]);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/*
|
||||
* postprocessing of fields type many2many
|
||||
* make the rpc request for all ids/model and insert value inside .oe_tags fields
|
||||
*/
|
||||
postprocess_m2m_tags: function() {
|
||||
var self = this;
|
||||
if (!this.many2manys.length) {
|
||||
return;
|
||||
}
|
||||
var relations = {};
|
||||
this.groups.forEach(function(group) {
|
||||
group.records.forEach(function(record) {
|
||||
self.many2manys.forEach(function(name) {
|
||||
var field = record.record[name];
|
||||
var $el = record.$('.oe_form_field.oe_tags[name=' + name + ']').empty();
|
||||
if (!relations[field.relation]) {
|
||||
relations[field.relation] = { ids: [], elements: {}, context: self.m2m_context[name]};
|
||||
}
|
||||
var rel = relations[field.relation];
|
||||
field.raw_value.forEach(function(id) {
|
||||
rel.ids.push(id);
|
||||
if (!rel.elements[id]) {
|
||||
rel.elements[id] = [];
|
||||
}
|
||||
rel.elements[id].push($el[0]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
_.each(relations, function(rel, rel_name) {
|
||||
var dataset = new instance.web.DataSetSearch(self, rel_name, self.dataset.get_context(rel.context));
|
||||
call = false
|
||||
dataset.name_get(_.uniq(rel.ids)).then(function(result) {
|
||||
if(! call){
|
||||
result.forEach(function(nameget) {
|
||||
call = true
|
||||
$(rel.elements[nameget[0]]).append('<span class="oe_tag">' + _.str.escapeHTML(nameget[1]) + '</span>');
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
|
||||
do_process_groups: function(groups) {
|
||||
var self = this;
|
||||
this.$el.find('table:first').show();
|
||||
this.$el.removeClass('oe_kanban_ungrouped').addClass('oe_kanban_grouped');
|
||||
this.add_group_mutex.exec(function() {
|
||||
self.do_clear_groups();
|
||||
self.dataset.ids = [];
|
||||
if (!groups.length) {
|
||||
self.no_result();
|
||||
return false;
|
||||
}
|
||||
self.nb_records = 0;
|
||||
var groups_array = [];
|
||||
return $.when.apply(null, _.map(groups, function (group, index) {
|
||||
var def = $.when([]);
|
||||
var dataset = new instance.web.DataSetSearch(self, self.dataset.model,
|
||||
new instance.web.CompoundContext(self.dataset.get_context(), group.model.context()), group.model.domain());
|
||||
if (self.dataset._sort) {
|
||||
dataset.set_sort(self.dataset._sort);
|
||||
}
|
||||
if (group.attributes.length >= 1) {
|
||||
def = dataset.read_slice(self.fields_keys.concat(['__last_update']), { 'limit': self.limit });
|
||||
}
|
||||
return def.then(function(records) {
|
||||
self.nb_records += records.length;
|
||||
self.dataset.ids.push.apply(self.dataset.ids, dataset.ids);
|
||||
dataset.o2m_field = self.dataset.o2m_field
|
||||
groups_array[index] = new instance.web_kanban.KanbanGroup(self, records, group, dataset);
|
||||
});
|
||||
})).then(function () {
|
||||
if(!self.nb_records) {
|
||||
self.no_result();
|
||||
}
|
||||
if (self.dataset.index >= self.nb_records){
|
||||
self.dataset.index = self.dataset.size() ? 0 : null;
|
||||
}
|
||||
return self.do_add_groups(groups_array);
|
||||
});
|
||||
});
|
||||
},
|
||||
})
|
||||
|
||||
instance.web_kanban.KanbanGroup.include({
|
||||
|
||||
do_add_records: function(records, prepend) {
|
||||
var self = this;
|
||||
var $list_header = this.$records.find('.oe_kanban_group_list_header');
|
||||
var $show_more = this.$records.find('.oe_kanban_show_more');
|
||||
var $cards = this.$records.find('.oe_kanban_column_cards');
|
||||
var record_length = records.length
|
||||
_.each(records, function(record) {
|
||||
if(_.keys(self.dataset.o2m_field).length){
|
||||
var count = 0
|
||||
_.each(self.dataset.o2m_field,function(data,index){
|
||||
var ids = record[data.field_name];
|
||||
var model = data.model
|
||||
var fields = data.fields
|
||||
self.o2m_dataset = new instance.web.DataSetSearch(self, model, {}, []);
|
||||
self.o2m_dataset.read_slice(fields, {'domain': [['id', 'in', ids]]}).then(function(field_record){
|
||||
|
||||
record[data.field_name] = field_record
|
||||
count ++ ;
|
||||
var rec = new instance.web_kanban.KanbanRecord(self, record);
|
||||
if(count == _.keys(self.dataset.o2m_field).length){
|
||||
if (!prepend) {
|
||||
rec.appendTo($cards);
|
||||
self.records.push(rec);
|
||||
} else {
|
||||
rec.prependTo($cards);
|
||||
self.records.unshift(rec);
|
||||
}
|
||||
if(self.records.length == record_length ){
|
||||
self.view.postprocess_m2m_tags();
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
}else{
|
||||
var rec = new instance.web_kanban.KanbanRecord(self, record);
|
||||
if (!prepend) {
|
||||
rec.appendTo($cards);
|
||||
self.records.push(rec);
|
||||
} else {
|
||||
rec.prependTo($cards);
|
||||
self.records.unshift(rec);
|
||||
}
|
||||
}
|
||||
});
|
||||
if ($show_more.length) {
|
||||
var size = this.dataset.size();
|
||||
$show_more.toggle(record_length < size).find('.oe_kanban_remaining').text(size - this.records.length);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
instance.web_kanban.KanbanRecord.include({
|
||||
do_reload: function() {
|
||||
var self = this;
|
||||
this.view.dataset.read_ids([this.id], this.view.fields_keys.concat(['__last_update'])).done(function(records) {
|
||||
_.each(self.sub_widgets, function(el) {
|
||||
el.destroy();
|
||||
});
|
||||
self.sub_widgets = [];
|
||||
if(_.keys(self.view.dataset.o2m_field).length){
|
||||
var count = 0
|
||||
_.each(self.view.dataset.o2m_field,function(data,index){
|
||||
var ids = records[0][data.field_name];
|
||||
var fields = data.fields
|
||||
var model = data.model
|
||||
self.o2m_dataset = new instance.web.DataSetSearch(self, model, {}, []);
|
||||
self.o2m_dataset.read_slice(fields, {'domain': [['id', 'in', ids]]}).then(function(field_record){
|
||||
count ++ ;
|
||||
if(count == _.keys(self.view.dataset.o2m_field).length){
|
||||
records[0][data.field_name] = field_record
|
||||
self.set_record(records[0]);
|
||||
self.renderElement();
|
||||
self.init_content();
|
||||
self.group.compute_cards_auto_height();
|
||||
self.view.postprocess_m2m_tags();
|
||||
}
|
||||
});
|
||||
});
|
||||
}else{
|
||||
if (records.length) {
|
||||
self.set_record(records[0]);
|
||||
self.renderElement();
|
||||
self.init_content();
|
||||
self.group.compute_cards_auto_height();
|
||||
self.view.postprocess_m2m_tags();
|
||||
} else {
|
||||
self.destroy();
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
}
|
12
web_one2many_kanban/view/templates.xml
Normal file
12
web_one2many_kanban/view/templates.xml
Normal file
@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- vim:fdn=3:
|
||||
-->
|
||||
<openerp>
|
||||
<data>
|
||||
<template id="assets_backend" name="mrp_assets" inherit_id="web.assets_backend">
|
||||
<xpath expr="." position="inside">
|
||||
<script type="text/javascript" src="/web_one2many_kanban/static/src/js/web_one2many_kanban.js"></script>
|
||||
</xpath>
|
||||
</template>
|
||||
</data>
|
||||
</openerp>
|
Loading…
x
Reference in New Issue
Block a user