[MIG] kpi_dashboard: migration to 13.0
parent
de5a435343
commit
c708de0679
|
@ -5,11 +5,11 @@
|
|||
"name": "Kpi Dashboard",
|
||||
"summary": """
|
||||
Create Dashboards using kpis""",
|
||||
"version": "12.0.1.3.0",
|
||||
"version": "13.0.1.0.0",
|
||||
"license": "AGPL-3",
|
||||
"author": "Creu Blanca,Odoo Community Association (OCA)",
|
||||
"website": "https://github.com/OCA/reporting-engine",
|
||||
"depends": ["bus", "board", "base_sparse_field", "web_widget_color"],
|
||||
"depends": ["bus", "board", "base_sparse_field"],
|
||||
"qweb": ["static/src/xml/dashboard.xml"],
|
||||
"data": [
|
||||
"wizards/kpi_dashboard_menu.xml",
|
||||
|
|
|
@ -134,7 +134,6 @@ class KpiKpi(models.Model):
|
|||
self.ensure_one()
|
||||
self.cron_id = self.env["ir.cron"].create(self._cron_vals())
|
||||
|
||||
@api.multi
|
||||
def write(self, vals):
|
||||
if "value" in vals:
|
||||
vals["value_last_update"] = fields.Datetime.now()
|
||||
|
@ -165,8 +164,10 @@ class KpiKpi(models.Model):
|
|||
)
|
||||
results = self._get_code_input_dict()
|
||||
savepoint = "kpi_formula_%s" % self.id
|
||||
# pylint: disable=E8103
|
||||
self.env.cr.execute("savepoint %s" % savepoint)
|
||||
safe_eval(self.code or "", results, mode="exec", nocopy=True)
|
||||
# pylint: disable=E8103
|
||||
self.env.cr.execute("rollback to %s" % savepoint)
|
||||
return results.get("result", {})
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,427 @@
|
|||
/* nvd3 version 1.8.2-dev (https://github.com/novus/nvd3) 2016-02-08 */
|
||||
.nvd3 .nv-axis {
|
||||
pointer-events:none;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.nvd3 .nv-axis path {
|
||||
fill: none;
|
||||
stroke: #000;
|
||||
stroke-opacity: .75;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
|
||||
.nvd3 .nv-axis path.domain {
|
||||
stroke-opacity: .75;
|
||||
}
|
||||
|
||||
.nvd3 .nv-axis.nv-x path.domain {
|
||||
stroke-opacity: 0;
|
||||
}
|
||||
|
||||
.nvd3 .nv-axis line {
|
||||
fill: none;
|
||||
stroke: #e5e5e5;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
|
||||
.nvd3 .nv-axis .zero line,
|
||||
/*this selector may not be necessary*/ .nvd3 .nv-axis line.zero {
|
||||
stroke-opacity: .75;
|
||||
}
|
||||
|
||||
.nvd3 .nv-axis .nv-axisMaxMin text {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.nvd3 .x .nv-axis .nv-axisMaxMin text,
|
||||
.nvd3 .x2 .nv-axis .nv-axisMaxMin text,
|
||||
.nvd3 .x3 .nv-axis .nv-axisMaxMin text {
|
||||
text-anchor: middle
|
||||
}
|
||||
|
||||
.nvd3 .nv-axis.nv-disabled {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
/* scatter */
|
||||
.nvd3 .nv-groups .nv-point.hover {
|
||||
stroke-width: 20px;
|
||||
stroke-opacity: .5;
|
||||
}
|
||||
|
||||
.nvd3 .nv-scatter .nv-point.hover {
|
||||
fill-opacity: 1;
|
||||
}
|
||||
.nv-noninteractive {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.nv-distx, .nv-disty {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nvtooltip {
|
||||
position: absolute;
|
||||
background-color: rgba(255,255,255,1.0);
|
||||
color: rgba(0,0,0,1.0);
|
||||
padding: 1px;
|
||||
border: 1px solid rgba(0,0,0,.2);
|
||||
z-index: 10000;
|
||||
display: block;
|
||||
|
||||
font-family: Arial;
|
||||
font-size: 13px;
|
||||
text-align: left;
|
||||
pointer-events: none;
|
||||
|
||||
white-space: nowrap;
|
||||
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.nvtooltip {
|
||||
background: rgba(255,255,255, 0.8);
|
||||
border: 1px solid rgba(0,0,0,0.5);
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
/*Give tooltips that old fade in transition by
|
||||
putting a "with-transitions" class on the container div.
|
||||
*/
|
||||
.nvtooltip.with-transitions, .with-transitions .nvtooltip {
|
||||
transition: opacity 50ms linear;
|
||||
-moz-transition: opacity 50ms linear;
|
||||
-webkit-transition: opacity 50ms linear;
|
||||
|
||||
transition-delay: 200ms;
|
||||
-moz-transition-delay: 200ms;
|
||||
-webkit-transition-delay: 200ms;
|
||||
}
|
||||
|
||||
.nvtooltip.x-nvtooltip,
|
||||
.nvtooltip.y-nvtooltip {
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
.nvtooltip h3 {
|
||||
margin: 0;
|
||||
padding: 4px 14px;
|
||||
line-height: 18px;
|
||||
font-weight: normal;
|
||||
background-color: rgba(247,247,247,0.75);
|
||||
color: rgba(0,0,0,1.0);
|
||||
text-align: center;
|
||||
|
||||
border-bottom: 1px solid #ebebeb;
|
||||
|
||||
-webkit-border-radius: 5px 5px 0 0;
|
||||
-moz-border-radius: 5px 5px 0 0;
|
||||
border-radius: 5px 5px 0 0;
|
||||
}
|
||||
|
||||
.nvtooltip p {
|
||||
margin: 0;
|
||||
padding: 5px 14px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.nvtooltip span {
|
||||
display: inline-block;
|
||||
margin: 2px 0;
|
||||
}
|
||||
|
||||
.nvtooltip table {
|
||||
margin: 6px;
|
||||
border-spacing:0;
|
||||
}
|
||||
|
||||
|
||||
.nvtooltip table td {
|
||||
padding: 2px 9px 2px 0;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.nvtooltip table td.key {
|
||||
font-weight: normal;
|
||||
}
|
||||
.nvtooltip table td.key.total {
|
||||
font-weight: bold;
|
||||
}
|
||||
.nvtooltip table td.value {
|
||||
text-align: right;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.nvtooltip table tr.highlight td {
|
||||
padding: 1px 9px 1px 0;
|
||||
border-bottom-style: solid;
|
||||
border-bottom-width: 1px;
|
||||
border-top-style: solid;
|
||||
border-top-width: 1px;
|
||||
}
|
||||
|
||||
.nvtooltip table td.legend-color-guide div {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.nvtooltip table td.legend-color-guide div {
|
||||
width: 12px;
|
||||
height: 12px;
|
||||
border: 1px solid #999;
|
||||
}
|
||||
|
||||
.nvtooltip .footer {
|
||||
padding: 3px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.nvtooltip-pending-removal {
|
||||
pointer-events: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/****
|
||||
Interactive Layer
|
||||
*/
|
||||
.nvd3 .nv-interactiveGuideLine {
|
||||
pointer-events:none;
|
||||
}
|
||||
.nvd3 line.nv-guideline {
|
||||
stroke: #ccc;
|
||||
}
|
||||
|
||||
.nvd3 .nv-bars rect {
|
||||
fill-opacity: .75;
|
||||
|
||||
transition: fill-opacity 250ms linear;
|
||||
-moz-transition: fill-opacity 250ms linear;
|
||||
-webkit-transition: fill-opacity 250ms linear;
|
||||
}
|
||||
|
||||
.nvd3 .nv-bars rect.hover {
|
||||
fill-opacity: 1;
|
||||
}
|
||||
|
||||
.nvd3 .nv-bars .hover rect {
|
||||
fill: lightblue;
|
||||
}
|
||||
|
||||
.nvd3 .nv-bars text {
|
||||
fill: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
.nvd3 .nv-bars .hover text {
|
||||
fill: rgba(0,0,0,1);
|
||||
}
|
||||
|
||||
.nvd3 .nv-multibar .nv-groups rect,
|
||||
.nvd3 .nv-multibarHorizontal .nv-groups rect,
|
||||
.nvd3 .nv-discretebar .nv-groups rect {
|
||||
stroke-opacity: 0;
|
||||
|
||||
transition: fill-opacity 250ms linear;
|
||||
-moz-transition: fill-opacity 250ms linear;
|
||||
-webkit-transition: fill-opacity 250ms linear;
|
||||
}
|
||||
|
||||
.nvd3 .nv-multibar .nv-groups rect:hover,
|
||||
.nvd3 .nv-multibarHorizontal .nv-groups rect:hover,
|
||||
.nvd3 .nv-candlestickBar .nv-ticks rect:hover,
|
||||
.nvd3 .nv-discretebar .nv-groups rect:hover {
|
||||
fill-opacity: 1;
|
||||
}
|
||||
|
||||
.nvd3 .nv-discretebar .nv-groups text,
|
||||
.nvd3 .nv-multibarHorizontal .nv-groups text {
|
||||
font-weight: bold;
|
||||
fill: rgba(0,0,0,1);
|
||||
stroke: rgba(0,0,0,0);
|
||||
}
|
||||
|
||||
.nvd3 .nv-groups path.nv-line {
|
||||
fill: none;
|
||||
}
|
||||
|
||||
.nvd3 .nv-groups path.nv-area {
|
||||
stroke: none;
|
||||
}
|
||||
|
||||
.nvd3.nv-line .nvd3.nv-scatter .nv-groups .nv-point {
|
||||
fill-opacity: 0;
|
||||
stroke-opacity: 0;
|
||||
}
|
||||
|
||||
.nvd3.nv-scatter.nv-single-point .nv-groups .nv-point {
|
||||
fill-opacity: .5 !important;
|
||||
stroke-opacity: .5 !important;
|
||||
}
|
||||
|
||||
|
||||
.with-transitions .nvd3 .nv-groups .nv-point {
|
||||
transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
|
||||
-moz-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
|
||||
-webkit-transition: stroke-width 250ms linear, stroke-opacity 250ms linear;
|
||||
|
||||
}
|
||||
|
||||
.nvd3.nv-scatter .nv-groups .nv-point.hover,
|
||||
.nvd3 .nv-groups .nv-point.hover {
|
||||
stroke-width: 7px;
|
||||
fill-opacity: .95 !important;
|
||||
stroke-opacity: .95 !important;
|
||||
}
|
||||
|
||||
|
||||
.nvd3 .nv-point-paths path {
|
||||
stroke: #aaa;
|
||||
stroke-opacity: 0;
|
||||
fill: #eee;
|
||||
fill-opacity: 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
.nvd3 .nv-indexLine {
|
||||
cursor: ew-resize;
|
||||
}
|
||||
|
||||
/********************
|
||||
* SVG CSS
|
||||
*/
|
||||
|
||||
/********************
|
||||
Default CSS for an svg element nvd3 used
|
||||
*/
|
||||
svg.nvd3-svg {
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-ms-user-select: none;
|
||||
-moz-user-select: none;
|
||||
user-select: none;
|
||||
display: block;
|
||||
width:100%;
|
||||
height:100%;
|
||||
}
|
||||
|
||||
/********************
|
||||
Box shadow and border radius styling
|
||||
*/
|
||||
.nvtooltip.with-3d-shadow, .with-3d-shadow .nvtooltip {
|
||||
-moz-box-shadow: 0 5px 10px rgba(0,0,0,.2);
|
||||
-webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2);
|
||||
box-shadow: 0 5px 10px rgba(0,0,0,.2);
|
||||
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
|
||||
.nvd3 text {
|
||||
font: normal 12px Arial;
|
||||
}
|
||||
|
||||
.nvd3 .title {
|
||||
font: bold 14px Arial;
|
||||
}
|
||||
|
||||
.nvd3 .nv-background {
|
||||
fill: white;
|
||||
fill-opacity: 0;
|
||||
}
|
||||
|
||||
.nvd3.nv-noData {
|
||||
font-size: 18px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/**********
|
||||
* Brush
|
||||
*/
|
||||
|
||||
.nv-brush .extent {
|
||||
fill-opacity: .125;
|
||||
shape-rendering: crispEdges;
|
||||
}
|
||||
|
||||
.nv-brush .resize path {
|
||||
fill: #eee;
|
||||
stroke: #666;
|
||||
}
|
||||
|
||||
|
||||
/**********
|
||||
* Legend
|
||||
*/
|
||||
|
||||
.nvd3 .nv-legend .nv-series {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nvd3 .nv-legend .nv-disabled circle {
|
||||
fill-opacity: 0;
|
||||
}
|
||||
|
||||
/* focus */
|
||||
.nvd3 .nv-brush .extent {
|
||||
fill-opacity: 0 !important;
|
||||
}
|
||||
|
||||
.nvd3 .nv-brushBackground rect {
|
||||
stroke: #000;
|
||||
stroke-width: .4;
|
||||
fill: #fff;
|
||||
fill-opacity: .7;
|
||||
}
|
||||
|
||||
|
||||
.nvd3.nv-pie path {
|
||||
stroke-opacity: 0;
|
||||
transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
|
||||
-moz-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
|
||||
-webkit-transition: fill-opacity 250ms linear, stroke-width 250ms linear, stroke-opacity 250ms linear;
|
||||
|
||||
}
|
||||
|
||||
.nvd3.nv-pie .nv-pie-title {
|
||||
font-size: 24px;
|
||||
fill: rgba(19, 196, 249, 0.59);
|
||||
}
|
||||
|
||||
.nvd3.nv-pie .nv-slice text {
|
||||
stroke: #000;
|
||||
stroke-width: 0;
|
||||
}
|
||||
|
||||
.nvd3.nv-pie path {
|
||||
stroke: #fff;
|
||||
stroke-width: 1px;
|
||||
stroke-opacity: 1;
|
||||
}
|
||||
|
||||
.nvd3.nv-pie path {
|
||||
fill-opacity: .7;
|
||||
}
|
||||
.nvd3.nv-pie .hover path {
|
||||
fill-opacity: 1;
|
||||
}
|
||||
.nvd3.nv-pie .nv-label {
|
||||
pointer-events: none;
|
||||
}
|
||||
.nvd3.nv-pie .nv-label rect {
|
||||
fill-opacity: 0;
|
||||
stroke-opacity: 0;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,3 +1,6 @@
|
|||
/*
|
||||
global py
|
||||
*/
|
||||
odoo.define("kpi_dashboard.DashboardController", function(require) {
|
||||
"use strict";
|
||||
|
||||
|
@ -20,7 +23,7 @@ odoo.define("kpi_dashboard.DashboardController", function(require) {
|
|||
add_modify_color: "_addModifyColor",
|
||||
refresh_colors: "_refreshColors",
|
||||
}),
|
||||
_refreshOnFly: function(event) {
|
||||
_refreshOnFly: function() {
|
||||
var self = this;
|
||||
this._rpc({
|
||||
model: this.modelName,
|
||||
|
@ -37,12 +40,14 @@ odoo.define("kpi_dashboard.DashboardController", function(require) {
|
|||
});
|
||||
},
|
||||
renderPager: function($node, options) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
options = _.extend({}, options, {
|
||||
validate: this.canBeDiscarded.bind(this),
|
||||
});
|
||||
this._super($node, options);
|
||||
},
|
||||
_pushState: function(state) {
|
||||
// eslint-disable-next-line no-param-reassign
|
||||
state = state || {};
|
||||
var env = this.model.get(this.handle, {env: true});
|
||||
state.id = env.currentId;
|
||||
|
|
|
@ -4,7 +4,7 @@ odoo.define("kpi_dashboard.DashboardModel", function(require) {
|
|||
var BasicModel = require("web.BasicModel");
|
||||
|
||||
var DashboardModel = BasicModel.extend({
|
||||
_fetchRecord: function(record, options) {
|
||||
_fetchRecord: function(record) {
|
||||
return this._rpc({
|
||||
model: record.model,
|
||||
method: "read_dashboard",
|
||||
|
|
|
@ -4,7 +4,6 @@ odoo.define("kpi_dashboard.DashboardRenderer", function(require) {
|
|||
var BasicRenderer = require("web.BasicRenderer");
|
||||
var core = require("web.core");
|
||||
var registry = require("kpi_dashboard.widget_registry");
|
||||
var BusService = require("bus.BusService");
|
||||
var qweb = core.qweb;
|
||||
|
||||
var DashboardRenderer = BasicRenderer.extend({
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
global nv
|
||||
*/
|
||||
odoo.define("web.nvd3.extensions", function() {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* The nvd3 library extensions and fixes should be done here to avoid patching
|
||||
* in place.
|
||||
*/
|
||||
|
||||
nv.dev = false;
|
||||
// Sets nvd3 library in production mode
|
||||
|
||||
// monkey patch nvd3 to allow removing eventhandler on windowresize events
|
||||
// see https://github.com/novus/nvd3/pull/396 for more details
|
||||
|
||||
// Adds a resize listener to the window.
|
||||
nv.utils.onWindowResize = function(fun) {
|
||||
if (fun === null) return;
|
||||
window.addEventListener("resize", fun);
|
||||
};
|
||||
|
||||
// Backwards compatibility with current API.
|
||||
nv.utils.windowResize = nv.utils.onWindowResize;
|
||||
|
||||
// Removes a resize listener from the window.
|
||||
nv.utils.offWindowResize = function(fun) {
|
||||
if (fun === null) return;
|
||||
window.removeEventListener("resize", fun);
|
||||
};
|
||||
|
||||
// Monkey patch nvd3 to prevent crashes when user changes view and nvd3
|
||||
// tries to remove tooltips after 500 ms... seriously nvd3, what were you
|
||||
// thinking?
|
||||
nv.tooltip.cleanup = function() {
|
||||
$(".nvtooltip").remove();
|
||||
};
|
||||
|
||||
// Monkey patch nvd3 to prevent it to display a tooltip (position: absolute)
|
||||
// with a negative `top`; with this patch the highest tooltip's position is
|
||||
// still in the graph
|
||||
var originalCalcTooltipPosition = nv.tooltip.calcTooltipPosition;
|
||||
nv.tooltip.calcTooltipPosition = function() {
|
||||
var container = originalCalcTooltipPosition.apply(this, arguments);
|
||||
container.style.top =
|
||||
container.style.top.split("px")[0] < 0 ? 0 + "px" : container.style.top;
|
||||
return container;
|
||||
};
|
||||
});
|
|
@ -7,9 +7,12 @@ odoo.define("kpi_dashboard.AbstractWidget", function(require) {
|
|||
var registry = require("kpi_dashboard.widget_registry");
|
||||
|
||||
var AbstractWidget = Widget.extend({
|
||||
template: "kpi_dashboard.base_widget", // Template used by the widget
|
||||
cssLibs: [], // Specific css of the widget
|
||||
jsLibs: [], // Specific Javascript libraries of the widget
|
||||
// Template used by the widget
|
||||
template: "kpi_dashboard.base_widget",
|
||||
// Specific css of the widget
|
||||
cssLibs: [],
|
||||
// Specific Javascript libraries of the widget
|
||||
jsLibs: [],
|
||||
events: {
|
||||
"click .o_kpi_dashboard_toggle_button": "_onClickToggleButton",
|
||||
"click .direct_action": "_onClickDirectAction",
|
||||
|
|
|
@ -3,7 +3,6 @@ odoo.define("kpi_dashboard.CounterWidget", function(require) {
|
|||
|
||||
var IntegerWidget = require("kpi_dashboard.IntegerWidget");
|
||||
var registry = require("kpi_dashboard.widget_registry");
|
||||
var field_utils = require("web.field_utils");
|
||||
|
||||
var CounterWidget = IntegerWidget.extend({
|
||||
shortList: [],
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
/*
|
||||
global nv, d3
|
||||
*/
|
||||
odoo.define("kpi_dashboard.GraphWidget", function(require) {
|
||||
"use strict";
|
||||
|
||||
|
@ -9,11 +12,11 @@ odoo.define("kpi_dashboard.GraphWidget", function(require) {
|
|||
var GraphWidget = AbstractWidget.extend({
|
||||
template: "kpi_dashboard.graph",
|
||||
jsLibs: [
|
||||
"/web/static/lib/nvd3/d3.v3.js",
|
||||
"/web/static/lib/nvd3/nv.d3.js",
|
||||
"/web/static/src/js/libs/nvd3.js",
|
||||
"/kpi_dashboard/static/lib/nvd3/d3.v3.js",
|
||||
"/kpi_dashboard/static/lib/nvd3/nv.d3.js",
|
||||
"/kpi_dashboard/static/src/js/lib/nvd3.js",
|
||||
],
|
||||
cssLibs: ["/web/static/lib/nvd3/nv.d3.css"],
|
||||
cssLibs: ["/kpi_dashboard/static/lib/nvd3/nv.d3.css"],
|
||||
start: function() {
|
||||
this._onResize = this._onResize.bind(this);
|
||||
nv.utils.windowResize(this._onResize);
|
||||
|
@ -28,7 +31,7 @@ odoo.define("kpi_dashboard.GraphWidget", function(require) {
|
|||
}
|
||||
this._super.apply(this, arguments);
|
||||
},
|
||||
_getChartOptions: function(values) {
|
||||
_getChartOptions: function() {
|
||||
return {
|
||||
x: function(d, u) {
|
||||
return u;
|
||||
|
|
|
@ -18,16 +18,17 @@ odoo.define("kpi_dashboard.IntegerWidget", function(require) {
|
|||
var suffix = "";
|
||||
var shortened = false;
|
||||
var digits = this.digits;
|
||||
var result = num;
|
||||
_.each(this.shortList, function(shortItem) {
|
||||
if (!shortened && Math.abs(num) >= shortItem[0]) {
|
||||
shortened = true;
|
||||
suffix = shortItem[1];
|
||||
num /= shortItem[0];
|
||||
result /= shortItem[0];
|
||||
digits = shortItem[2];
|
||||
}
|
||||
});
|
||||
return (
|
||||
field_utils.format.float(num, false, {
|
||||
field_utils.format.float(result, false, {
|
||||
digits: digits,
|
||||
}) + suffix
|
||||
);
|
||||
|
|
|
@ -21,8 +21,8 @@ odoo.define("kpi_dashboard.MeterWidget", function(require) {
|
|||
style: "Arch",
|
||||
width: 10,
|
||||
size: size,
|
||||
prepend: values.prefix !== undefined ? values.prefix : "",
|
||||
append: values.suffix !== undefined ? values.suffix : "",
|
||||
prepend: values.prefix === undefined ? "" : values.prefix,
|
||||
append: values.suffix === undefined ? "" : values.suffix,
|
||||
color: values.font_color,
|
||||
animate_text_colors: true,
|
||||
};
|
||||
|
|
|
@ -9,7 +9,7 @@ class TestFormula(TransactionCase):
|
|||
def setUp(self):
|
||||
super().setUp()
|
||||
self.kpi = self.env["kpi.kpi"].create(
|
||||
{"name": "DEMO KPI", "widget": "number", "computation_method": "code",}
|
||||
{"name": "DEMO KPI", "widget": "number", "computation_method": "code"}
|
||||
)
|
||||
|
||||
def test_forbidden_words_01(self):
|
||||
|
@ -45,8 +45,7 @@ result = {{}}
|
|||
result['value'] = len(model.search([('id', '=', {})]))
|
||||
result['previous'] = len(model.search([('id', '!=', {})]))
|
||||
""".format(
|
||||
self.kpi.id,
|
||||
self.kpi.id,
|
||||
self.kpi.id, self.kpi.id,
|
||||
)
|
||||
self.kpi.compute()
|
||||
value = self.kpi.value
|
||||
|
@ -66,8 +65,7 @@ result = {{}}
|
|||
result['value'] = len(model.search([('id', '=', {})]))
|
||||
result['previous'] = len(model.search([('id', '!=', {})]))
|
||||
""".format(
|
||||
self.kpi.id,
|
||||
self.kpi.id,
|
||||
self.kpi.id, self.kpi.id,
|
||||
)
|
||||
self.kpi.compute()
|
||||
value = self.kpi.value
|
||||
|
|
|
@ -53,16 +53,18 @@ class TestKpiDashboard(TransactionCase):
|
|||
}
|
||||
)
|
||||
self.env["kpi.dashboard.item"].create(
|
||||
{"dashboard_id": self.dashboard.id, "name": "TITLE", "row": 2, "column": 1,}
|
||||
{"dashboard_id": self.dashboard.id, "name": "TITLE", "row": 2, "column": 1}
|
||||
)
|
||||
|
||||
def test_constrains_01(self):
|
||||
with self.assertRaises(ValidationError):
|
||||
self.kpi_01.dashboard_item_ids.write({"size_x": 2})
|
||||
self.kpi_01.flush()
|
||||
|
||||
def test_constrains_02(self):
|
||||
with self.assertRaises(ValidationError):
|
||||
self.kpi_02.dashboard_item_ids.write({"size_x": 4})
|
||||
self.kpi_01.flush()
|
||||
|
||||
def test_constrains_03(self):
|
||||
with self.assertRaises(ValidationError):
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# Copyright 2020 Creu Blanca
|
||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
|
||||
|
||||
from odoo import api, fields, models
|
||||
from odoo import fields, models
|
||||
|
||||
|
||||
class KpiDashboardMenu(models.TransientModel):
|
||||
|
@ -12,6 +12,5 @@ class KpiDashboardMenu(models.TransientModel):
|
|||
dashboard_id = fields.Many2one("kpi.dashboard", required=True)
|
||||
menu_id = fields.Many2one("ir.ui.menu")
|
||||
|
||||
@api.multi
|
||||
def generate_menu(self):
|
||||
self.dashboard_id._generate_menu(self.menu_id)
|
||||
|
|
Loading…
Reference in New Issue