[IMP] crm,sale_crm: kanban widget

bzr revid: chm@openerp.com-20130503154652-r9mv3zovs8lnpj3e
This commit is contained in:
Christophe Matthieu 2013-05-03 17:46:52 +02:00
parent a26c8d76b9
commit 0c9110c7f7
8 changed files with 80 additions and 119 deletions

View File

@ -122,7 +122,6 @@ Dashboard for CRM will include:
'js': [
'static/src/js/crm_case_section.js',
'static/lib/sparkline/jquery.sparkline.min.js',
'static/lib/justgage.js',
],
'installable': True,
'application': True,

View File

@ -101,11 +101,11 @@
<div class="oe_items_list">
<div>
<a t-if="record.use_leads.raw_value" name="%(crm_case_form_view_salesteams_lead)d" type="action">Leads</a>
<a name="%(action_report_crm_lead)d" type="action" class="oe_sparkline_bar" t-att-data-value="record.open_lead_per_duration.raw_value">Number of opening leads per duration.<br/>(last one is <t t-esc="record.target_duration_txt.value"/>).<br/>Click to acces the Leads Analysis</a>
<a name="%(action_report_crm_lead)d" type="action" class="oe_sparkline_bar_link"><field name="open_lead_per_duration" widget="sparkline_bar">Number of opening leads per duration.<br/>(last one is <t t-esc="record.target_duration_txt.value"/>).<br/>Click to acces the Leads Analysis</field></a>
</div>
<div>
<a name="%(crm_case_form_view_salesteams_opportunity)d" type="action">Opportunities</a>
<a name="%(action_report_crm_opportunity)d" type="action" class="oe_sparkline_bar" t-att-data-value="record.won_opportunity_per_duration.raw_value">Revenue of won opportunities per duration.<br/>(last one is <t t-esc="record.target_duration_txt.value"/>).<br/>Click to acces the Opportunities Analysis</a>
<a name="%(action_report_crm_opportunity)d" type="action"><field name="won_opportunity_per_duration" widget="sparkline_bar">Revenue of won opportunities per duration.<br/>(last one is <t t-esc="record.target_duration_txt.value"/>).<br/>Click to acces the Opportunities Analysis</field></a>
</div>
</div>
</div>

View File

@ -24,27 +24,23 @@
margin: 10px;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div {
width: 120px;
width: 160px;
height: 22px;
margin: 0;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div:nth-child(2n) {
position: absolute;
right: 0px;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div:nth-child(2n) a {
position: relative;
top: -20px;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_kanban_content > div {
clear: both;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div a:first-child {
width: 80px;
display: inline-block;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list a:hover {
text-decoration: underline !important;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div a:nth-child(2n) {
position: absolute;
left: 90px;
top: 0;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_items_list div:nth-child(2n) a:nth-child(2n) {
left: 110px;
}
.openerp .oe_kanban_view .oe_kanban_crm_salesteams .oe_center {
text-align: center;
margin: 3px 0;
@ -63,6 +59,6 @@
}
.openerp .oe_kanban_view .oe_sparkline_bar {
float: right;
height: 20px;
width: 36px;
}

View File

@ -1,93 +1,5 @@
openerp.crm = function(openerp) {
openerp.web_kanban.KanbanRecord.include({
renderElement: function () {
var rendering = this._super();
if (this.view.dataset.model === 'crm.case.section') {
var self = this;
$.when(rendering).done(function() {
self.$(".oe_justgage").each(function () {
var $el = $(this);
var title = $el.html();
var unique_id = _.uniqueId("JustGage");
$el.empty().css("position", "relative").attr('id', unique_id);
new JustGage({
id: unique_id,
node: this,
title: title,
value: +$el.data('value'),
min: 0,
max: +$el.data('max'),
relativeGaugeSize: true,
humanFriendly: true,
titleFontColor: '#333333',
valueFontColor: '#333333',
labelFontColor: '#000',
label: $el.data('label'),
levelColors: [
"#ff0000",
"#f9c802",
"#a9d70b"
],
});
var flag_open = false;
if ($el.data('action')) {
$el.click(function (event) {
event.stopPropagation();
flag_open = false;
if (!self.view.is_action_enabled('edit')) {
return;
}
if (!$el.find(".oe_justgage_edit").size()) {
var $svg = $el.find('svg');
$div = $('<div class="oe_justgage_edit" style="text-align: center; z-index: 1; position: absolute; width: ' + $svg.outerWidth() + 'px; top: ' + ($svg.outerHeight()/2-5) + 'px;"/>');
$input = $('<input style="text-align: center; width: ' + ($svg.outerWidth()-40) + 'px; margin: auto;"/>').val($el.data('value'));
$div.append($input);
$el.prepend($div)
$input.focus()
.keydown(function (event) {
event.stopPropagation();
if (event.keyCode == 13 || event.keyCode == 9) {
if ($input.val() != $el.data('value')) {
self.view.dataset.call($el.data('action'), [self.id, $input.val()]).then(function () {
self.do_reload();
});
} else {
$div.remove();
}
}
})
.click(function (event) {
event.stopPropagation();
flag_open = false;
})
.blur(function (event) {
if(!flag_open) {
$el.find(".oe_justgage_edit").remove();
} else {
flag_open = false;
setTimeout(function () {$input.focus();}, 0);
}
});
}
}).mousedown(function () {
flag_open = true;
});
}
});
setTimeout(function () {
self.$(".oe_sparkline_bar").each(function () {
var $el = $(this);
$el.data("title", $el.html());
$el.sparkline($el.data("value").split(','), {type: 'bar', barWidth: 5} );
$el.tipsy({'delayIn': 0, 'html': true, 'title': function(){return $(this).data("title")}, 'gravity': 'n'});
});
}, 0);
});
}
},
on_card_clicked: function() {
if (this.view.dataset.model === 'crm.case.section') {
this.$('.oe_kanban_crm_salesteams_list a').first().click();
@ -97,4 +9,17 @@ openerp.crm = function(openerp) {
},
});
openerp.crm.SparklineBarWidget = openerp.web_kanban.AbstractField.extend({
className: "oe_sparkline_bar",
start: function() {
var self = this;
var title = this.$node.html();
setTimeout(function () {
self.$el.sparkline(self.field.value, {type: 'bar', barWidth: 5} );
self.$el.tipsy({'delayIn': 0, 'html': true, 'title': function(){return title}, 'gravity': 'n'});
}, 0);
},
});
openerp.web_kanban.fields_registry.add("sparkline_bar", "openerp.crm.SparklineBarWidget");
};

View File

@ -47,6 +47,10 @@ modules.
'security/ir.model.access.csv',
'report/sale_crm_account_invoice_report_view.xml',
],
'js': [
'static/src/js/sale_crm.js',
'static/lib/justgage.js',
],
'demo': ['sale_crm_demo.xml'],
'test': ['test/sale_crm.yml'],
'installable': True,

View File

@ -234,29 +234,22 @@
</xpath>
<xpath expr="//div[@class='oe_items_list']" position="inside">
<div>
<a name="%(action_quotations_salesteams)d" type="action">Quotations</a>
<a name="%(sale.action_order_report_all)d" type="action" class="oe_sparkline_bar" t-att-data-value="record.created_quotation_per_duration.raw_value">Revenue of created quotation per <t t-esc="record.target_duration_txt.value"/>.<br/>Click to acces the Sales Analysis</a>
<a name="%(action_quotations_salesteams)d" type="action" class="oe_sparkline_bar_link">Quotations</a>
<a name="%(sale.action_order_report_all)d" type="action" class="oe_sparkline_bar_link"><field name="created_quotation_per_duration" widget="sparkline_bar">Revenue of created quotation per <t t-esc="record.target_duration_txt.value"/>.<br/>Click to acces the Sales Analysis</field></a>
</div>
<div>
<a name="%(action_orders_salesteams)d" type="action">Sales Orders</a>
<a name="%(sale.action_order_report_all)d" type="action" class="oe_sparkline_bar" t-att-data-value="record.validate_saleorder_per_duration.raw_value">Revenue of confirmed sales orders per <t t-esc="record.target_duration_txt.value"/>).<br/>Click the acces to Sales Analysis</a>
<a name="%(sale.action_order_report_all)d" type="action" class="oe_sparkline_bar_link"><field name="validate_saleorder_per_duration" widget="sparkline_bar">Revenue of confirmed sales orders per <t t-esc="record.target_duration_txt.value"/>).<br/>Click the acces to Sales Analysis</field></a>
</div>
<div>
<a name="%(action_invoice_salesteams)d" type="action" groups="account.group_account_invoice">Invoices</a>
<a name="%(account.action_account_invoice_report_all)d" type="action" class="oe_sparkline_bar" t-att-data-value="record.sent_invoice_per_duration.raw_value">Revenue of sent invoices per <t t-esc="record.target_duration_txt.value"/>.<br/>Click to acces the Invoices Analysis</a>
<a name="%(account.action_account_invoice_report_all)d" type="action" class="oe_sparkline_bar_link"><field name="sent_invoice_per_duration" widget="sparkline_bar">Revenue of sent invoices per <t t-esc="record.target_duration_txt.value"/>.<br/>Click to acces the Invoices Analysis</field></a>
</div>
</xpath>
<xpath expr="//div[@class='oe_items_list']" position="after">
<div class="oe_center" t-if="record.target_invoice.raw_value">
<div class="oe_justgage" style="width:160px; height: 120px;"
t-att-data-value="record.sent_invoice_per_duration.raw_value.pop()"
t-att-data-max="record.target_invoice.raw_value"
t-att-data-label="_.str.sprintf(_t('this %%s'), record.target_duration_txt.value)">Invoiced</div>
<div class="oe_justgage" style="width:160px; height: 120px;"
t-att-data-value="record.forecast.raw_value"
t-att-data-max="record.target_invoice.raw_value"
t-att-data-label="_.str.sprintf(_t('this %%s'), record.target_duration_txt.value)"
data-action="action_forecast">Forecast</div>
<field name="sent_invoice_per_duration" widget="gage" style="width:160px; height: 120px;" options="{'max_field': 'target_invoice', 'label_field': 'target_duration_txt'}">Invoiced</field>
<field name="forecast" widget="gage" style="width:160px; height: 120px;" options="{'max_field': 'target_invoice', 'label_field': 'target_duration_txt'}">Forecast</field>
</div>
<div class="oe_center" style="color:#bbbbbb;" t-if="!record.target_invoice.raw_value">
<br/>Not target invoicing defined

View File

@ -0,0 +1,44 @@
openerp.sale_crm = function(openerp) {
openerp.sale_crm.GaugeWidget = openerp.web_kanban.AbstractField.extend({
className: "oe_gage",
start: function() {
var max = 100;
if (this.options.max_field) {
max = this.getParent().record[this.options.max_field].raw_value;
}
var label = "";
if (this.options.label_field) {
label = this.getParent().record[this.options.label_field].raw_value;
}
var title = this.$node.html();
var value = _.isArray(this.field.value) ? this.field.value.pop() : this.field.value;
var unique_id = _.uniqueId("JustGage");
this.$el.empty()
.attr('style', this.$node.attr('style') + ';position:relative; display:inline-block;')
.attr('id', unique_id);
this.gage = new JustGage({
id: unique_id,
node: this.$el[0],
title: title,
value: value,
min: 0,
max: max,
relativeGaugeSize: true,
humanFriendly: true,
titleFontColor: '#333333',
valueFontColor: '#333333',
labelFontColor: '#000',
label: label,
levelColors: [
"#ff0000",
"#f9c802",
"#a9d70b"
],
});
},
});
openerp.web_kanban.fields_registry.add("gage", "openerp.sale_crm.GaugeWidget");
};