From ff1f9a49e5bfb75a8b725414e7211bb0c1456b53 Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Mon, 18 Jan 2016 16:41:25 +0100 Subject: [PATCH 1/4] [IMP] update to newest OCA template [ADD] example in readme --- web_widget_x2many_2d_matrix/README.rst | 50 ++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 7 deletions(-) diff --git a/web_widget_x2many_2d_matrix/README.rst b/web_widget_x2many_2d_matrix/README.rst index a6b436e1..a30feca6 100644 --- a/web_widget_x2many_2d_matrix/README.rst +++ b/web_widget_x2many_2d_matrix/README.rst @@ -1,3 +1,7 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :alt: License: AGPL-3 + +=========================== 2D matrix for x2many fields =========================== @@ -51,12 +55,42 @@ show_row_totals show_column_totals If field_value is a numeric field, calculate column totals +Example +======= + +You need a data structure already filled with values. Let's assume we want to use this widget in a wizard that lets the user fill in planned hours for one task per project per user. In this case, we can use ``project.task`` as our data model and point to it from our wizard. The crucial part is that we fill the field in the default function:: + + class MyWizard(models.TransientModel): + _name = 'my.wizard' + + def _default_task_ids(self): + # your list of project should come from the context, some selection + # in a previous wizard or wherever else + projects = self.env['project.project'].browse([1, 2, 3]) + # same with users + users = self.env['res.users'].browse([1, 2, 3]) + return [ + (0, 0, {'project_id': p.id, 'user_id': u.id, 'planned_hours': 0}) + # if the project doesn't have a task for the user, create a new one + if not p.task_ids.filtered(lambda x: x.user_id == u) else + # otherwise, return the task + (4, p.task_ids.filtered(lambda x: x.user_id == u)[0].id) + for p in projects + for u in users + ] + + task_ids = fields.Many2many('project.task', default=_default_task_ids) + +Now in our wizard, we can use:: + + + Known issues / Roadmap ====================== * it would be worth trying to instantiate the proper field widget and let it render the input - +=========== Bug Tracker =========== @@ -65,7 +99,7 @@ In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback `here `_. - +======= Credits ======= @@ -77,12 +111,14 @@ Contributors Maintainer ---------- -.. image:: http://odoo-community.org/logo.png - :alt: Odoo Community Association - :target: http://odoo-community.org +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org This module is maintained by the OCA. -OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. -To contribute to this module, please visit http://odoo-community.org. +To contribute to this module, please visit https://odoo-community.org. From f2e2aebbc7b0c7329ea2e5c3b330b26b26e035a7 Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Mon, 18 Jan 2016 16:41:47 +0100 Subject: [PATCH 2/4] [IMP] massive performance boost for big matrices especially on firefox --- .../src/js/web_widget_x2many_2d_matrix.js | 80 +++++++++++-------- 1 file changed, 48 insertions(+), 32 deletions(-) diff --git a/web_widget_x2many_2d_matrix/static/src/js/web_widget_x2many_2d_matrix.js b/web_widget_x2many_2d_matrix/static/src/js/web_widget_x2many_2d_matrix.js index 5d4ce785..06bb5d9c 100644 --- a/web_widget_x2many_2d_matrix/static/src/js/web_widget_x2many_2d_matrix.js +++ b/web_widget_x2many_2d_matrix/static/src/js/web_widget_x2many_2d_matrix.js @@ -31,6 +31,8 @@ openerp.web_widget_x2many_2d_matrix = function(instance) // those will be filled with rows from the dataset by_x_axis: {}, by_y_axis: {}, + by_id: {}, + // configuration values field_x_axis: 'x', field_label_x_axis: 'x', field_y_axis: 'y', @@ -81,7 +83,8 @@ openerp.web_widget_x2many_2d_matrix = function(instance) self.by_x_axis = {}; self.by_y_axis = {}; - + self.by_id = {}; + return jQuery.when(result).then(function() { return self.dataset._model.call('fields_get').then(function(fields) @@ -158,15 +161,29 @@ openerp.web_widget_x2many_2d_matrix = function(instance) }); }, - // to whatever needed to setup internal data structure + // do whatever needed to setup internal data structure add_xy_row: function(row) { var x = this.get_field_value(row, this.field_x_axis), y = this.get_field_value(row, this.field_y_axis); + // row is a *copy* of a row in dataset.cache, fetch + // a reference to this row in order to have the + // internal data structure point to the same data + // the dataset manipulates + _.every(this.dataset.cache, function(cached_row) + { + if(cached_row.id == row.id) + { + row = cached_row.values; + return false; + } + return true; + }); this.by_x_axis[x] = this.by_x_axis[x] || {}; this.by_y_axis[y] = this.by_y_axis[y] || {}; this.by_x_axis[x][y] = row; this.by_y_axis[y][x] = row; + this.by_id[row.id] = row; }, // get x axis values in the correct order @@ -255,39 +272,38 @@ openerp.web_widget_x2many_2d_matrix = function(instance) var self = this, grand_total = 0, totals_x = {}, - totals_y = {}; - return self.dataset.read_ids(self.dataset.ids).then(function(rows) + totals_y = {}, + rows = this.by_id, + deferred = jQuery.Deferred(); + _.each(rows, function(row) { - _.each(rows, function(row) - { - var key_x = self.get_field_value(row, self.field_x_axis), - key_y = self.get_field_value(row, self.field_y_axis); - totals_x[key_x] = (totals_x[key_x] || 0) + self.get_field_value(row, self.field_value); - totals_y[key_y] = (totals_y[key_y] || 0) + self.get_field_value(row, self.field_value); - grand_total += self.get_field_value(row, self.field_value); - }); - }).then(function() + var key_x = self.get_field_value(row, self.field_x_axis), + key_y = self.get_field_value(row, self.field_y_axis); + totals_x[key_x] = (totals_x[key_x] || 0) + self.get_field_value(row, self.field_value); + totals_y[key_y] = (totals_y[key_y] || 0) + self.get_field_value(row, self.field_value); + grand_total += self.get_field_value(row, self.field_value); + }); + _.each(totals_y, function(total, y) { - _.each(totals_y, function(total, y) - { - self.$el.find( - _.str.sprintf('td.row_total[data-y="%s"]', y)).text( - self.format_xy_value(total)); - }); - _.each(totals_x, function(total, x) - { - self.$el.find( - _.str.sprintf('td.column_total[data-x="%s"]', x)).text( - self.format_xy_value(total)); - }); - self.$el.find('.grand_total').text( - self.format_xy_value(grand_total)) - return { - totals_x: totals_x, - totals_y: totals_y, - grand_total: grand_total, - }; + self.$el.find( + _.str.sprintf('td.row_total[data-y="%s"]', y)).text( + self.format_xy_value(total)); + }); + _.each(totals_x, function(total, x) + { + self.$el.find( + _.str.sprintf('td.column_total[data-x="%s"]', x)).text( + self.format_xy_value(total)); + }); + self.$el.find('.grand_total').text( + self.format_xy_value(grand_total)) + deferred.resolve({ + totals_x: totals_x, + totals_y: totals_y, + grand_total: grand_total, + rows: rows, }); + return deferred; }, setup_many2one_axes: function() From 035b09ce8c2deaa277fc42f5c88fa96925ea8bdb Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Thu, 21 Jan 2016 13:30:57 +0100 Subject: [PATCH 3/4] [FIX] rebase artefacts --- web_widget_x2many_2d_matrix/README.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/web_widget_x2many_2d_matrix/README.rst b/web_widget_x2many_2d_matrix/README.rst index a30feca6..7c880b13 100644 --- a/web_widget_x2many_2d_matrix/README.rst +++ b/web_widget_x2many_2d_matrix/README.rst @@ -90,7 +90,6 @@ Known issues / Roadmap * it would be worth trying to instantiate the proper field widget and let it render the input -=========== Bug Tracker =========== @@ -99,7 +98,6 @@ In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed feedback `here `_. -======= Credits ======= From 9dc1b03852fb39268075662062c6f9ed0887de1d Mon Sep 17 00:00:00 2001 From: Holger Brunn Date: Tue, 26 Jan 2016 15:44:27 +0100 Subject: [PATCH 4/4] [FIX] assign id on row in order to find it back in all cases --- .../static/src/js/web_widget_x2many_2d_matrix.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/web_widget_x2many_2d_matrix/static/src/js/web_widget_x2many_2d_matrix.js b/web_widget_x2many_2d_matrix/static/src/js/web_widget_x2many_2d_matrix.js index 06bb5d9c..438d52b7 100644 --- a/web_widget_x2many_2d_matrix/static/src/js/web_widget_x2many_2d_matrix.js +++ b/web_widget_x2many_2d_matrix/static/src/js/web_widget_x2many_2d_matrix.js @@ -175,6 +175,8 @@ openerp.web_widget_x2many_2d_matrix = function(instance) if(cached_row.id == row.id) { row = cached_row.values; + // new rows don't have that + row.id = cached_row.id; return false; } return true;