diff --git a/web_widget_x2many_2d_matrix/README.rst b/web_widget_x2many_2d_matrix/README.rst index f03a1953e..605424218 100644 --- a/web_widget_x2many_2d_matrix/README.rst +++ b/web_widget_x2many_2d_matrix/README.rst @@ -1,11 +1,30 @@ -.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg - :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html - :alt: License: AGPL-3 - =========================== 2D matrix for x2many fields =========================== +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fweb-lightgray.png?logo=github + :target: https://github.com/OCA/web/tree/9.0/web_widget_x2many_2d_matrix + :alt: OCA/web +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/web-9-0/web-9-0-web_widget_x2many_2d_matrix + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png + :target: https://runbot.odoo-community.org/runbot/162/9.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + This module allows to show an x2many field with 3-tuples ($x_value, $y_value, $value) in a table @@ -22,13 +41,19 @@ An example use case would be: Select some projects and some employees so that a manager can easily fill in the planned_hours for one task per employee. The result could look like this: -.. image:: /web_widget_x2many_2d_matrix/static/description/screenshot.png +.. image:: https://raw.githubusercontent.com/web_widget_x2many_2d_matrix/static/description/screenshot.png :alt: Screenshot The beauty of this is that you have an arbitrary amount of columns with this widget, trying to get this in standard x2many lists involves some quite ugly hacks. + +**Table of contents** + +.. contents:: + :local: + Usage ===== @@ -71,10 +96,6 @@ field_att_ a field value with an HTML node attribute (disabled, class, style...) called as the `` passed in the option. -.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas - :alt: Try me on Runbot - :target: https://runbot.odoo-community.org/runbot/162/8.0 - Example ======= @@ -108,7 +129,7 @@ the field in the default function:: Now in our wizard, we can use:: - + Note that all values in the matrix must exist, so you need to create them previously if not present, but you can control visually the editability of @@ -122,46 +143,57 @@ Known issues / Roadmap * Let the widget deal with the missing values of the full Cartesian product, instead of being forced to pre-fill all the possible values. * If you pass values with an onchange, you need to overwrite the model's method - `onchange` for making the widget work:: + `onchange` for making the widget work: .. code-block:: python - @api.multi - def onchange(self, values, field_name, field_onchange): - if "one2many_field" in field_onchange: - for sub in []: - field_onchange.setdefault("one2many_field." + sub, u"") - return super(model, self).onchange(values, field_name, field_onchange) + @api.multi + def onchange(self, values, field_name, field_onchange): + if "one2many_field" in field_onchange: + for sub in []: + field_onchange.setdefault("one2many_field." + sub, u"") + return super(model, self).onchange(values, field_name, field_onchange) Bug Tracker =========== -Bugs are tracked on `GitHub Issues -`_. 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. +Bugs are tracked on `GitHub Issues `_. +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 `_. + +Do not contact contributors directly about support or help with technical issues. Credits ======= +Authors +~~~~~~~ + +* Therp BV +* Tecnativa + Contributors ------------- +~~~~~~~~~~~~ * Holger Brunn * Pedro M. Baeza -Maintainer ----------- + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. .. 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. -To contribute to this module, please visit https://odoo-community.org. +This module is part of the `OCA/web `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_widget_x2many_2d_matrix/readme/CONTRIBUTORS.rst b/web_widget_x2many_2d_matrix/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..6c312fee7 --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Holger Brunn +* Pedro M. Baeza + diff --git a/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst b/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst new file mode 100644 index 000000000..d1eb8261b --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/DESCRIPTION.rst @@ -0,0 +1,23 @@ +This module allows to show an x2many field with 3-tuples +($x_value, $y_value, $value) in a table + +========= =========== =========== +\ $x_value1 $x_value2 +========= =========== =========== +$y_value1 $value(1/1) $value(2/1) +$y_value2 $value(1/2) $value(2/2) +========= =========== =========== + +where `value(n/n)` is editable. + +An example use case would be: Select some projects and some employees so that +a manager can easily fill in the planned_hours for one task per employee. The +result could look like this: + +.. image:: /web_widget_x2many_2d_matrix/static/description/screenshot.png + :alt: Screenshot + +The beauty of this is that you have an arbitrary amount of columns with this +widget, trying to get this in standard x2many lists involves some quite ugly +hacks. + diff --git a/web_widget_x2many_2d_matrix/readme/ROADMAP.rst b/web_widget_x2many_2d_matrix/readme/ROADMAP.rst new file mode 100644 index 000000000..228f3f63d --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/ROADMAP.rst @@ -0,0 +1,15 @@ +* It would be worth trying to instantiate the proper field widget and let it render the input +* Let the widget deal with the missing values of the full Cartesian product, + instead of being forced to pre-fill all the possible values. +* If you pass values with an onchange, you need to overwrite the model's method + `onchange` for making the widget work: + +.. code-block:: python + + @api.multi + def onchange(self, values, field_name, field_onchange): + if "one2many_field" in field_onchange: + for sub in []: + field_onchange.setdefault("one2many_field." + sub, u"") + return super(model, self).onchange(values, field_name, field_onchange) + diff --git a/web_widget_x2many_2d_matrix/readme/USAGE.rst b/web_widget_x2many_2d_matrix/readme/USAGE.rst new file mode 100644 index 000000000..edbe28452 --- /dev/null +++ b/web_widget_x2many_2d_matrix/readme/USAGE.rst @@ -0,0 +1,78 @@ +Use this widget by saying:: + + + +This assumes that my_field refers to a model with the fields `x`, `y` and +`value`. If your fields are named differently, pass the correct names as +attributes:: + + + +You can pass the following parameters: + +field_x_axis + The field that indicates the x value of a point +field_y_axis + The field that indicates the y value of a point +field_label_x_axis + Use another field to display in the table header +field_label_y_axis + Use another field to display in the table header +x_axis_clickable + It indicates if the X axis allows to be clicked for navigating to the field + (if it's a many2one field). True by default +y_axis_clickable + It indicates if the Y axis allows to be clicked for navigating to the field + (if it's a many2one field). True by default +field_value + Show this field as value +show_row_totals + If field_value is a numeric field, it indicates if you want to calculate + row totals. True by default +show_column_totals + If field_value is a numeric field, it indicates if you want to calculate + column totals. True by default +field_att_ + Declare as many options prefixed with this string as you need for binding + a field value with an HTML node attribute (disabled, class, style...) + called as the `` passed in the option. + +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:: + + + +Note that all values in the matrix must exist, so you need to create them +previously if not present, but you can control visually the editability of +the fields in the matrix through `field_att_disabled` option with a control +field. diff --git a/web_widget_x2many_2d_matrix/static/description/index.html b/web_widget_x2many_2d_matrix/static/description/index.html new file mode 100644 index 000000000..a654eb0ac --- /dev/null +++ b/web_widget_x2many_2d_matrix/static/description/index.html @@ -0,0 +1,554 @@ + + + + + + +2D matrix for x2many fields + + + +
+

2D matrix for x2many fields

+ + +

Beta License: AGPL-3 OCA/web Translate me on Weblate Try me on Runbot

+

This module allows to show an x2many field with 3-tuples +($x_value, $y_value, $value) in a table

+ +++++ + + + + + + + + + + + + + + + + +
$x_value1$x_value2
$y_value1$value(1/1)$value(2/1)
$y_value2$value(1/2)$value(2/2)
+

where value(n/n) is editable.

+

An example use case would be: Select some projects and some employees so that +a manager can easily fill in the planned_hours for one task per employee. The +result could look like this:

+Screenshot +

The beauty of this is that you have an arbitrary amount of columns with this +widget, trying to get this in standard x2many lists involves some quite ugly +hacks.

+

Table of contents

+ +
+

Usage

+

Use this widget by saying:

+
+<field name="my_field" widget="x2many_2d_matrix" />
+
+

This assumes that my_field refers to a model with the fields x, y and +value. If your fields are named differently, pass the correct names as +attributes:

+
+<field name="my_field" widget="x2many_2d_matrix" field_x_axis="my_field1" field_y_axis="my_field2" field_value="my_field3" />
+
+

You can pass the following parameters:

+
+
field_x_axis
+
The field that indicates the x value of a point
+
field_y_axis
+
The field that indicates the y value of a point
+
field_label_x_axis
+
Use another field to display in the table header
+
field_label_y_axis
+
Use another field to display in the table header
+
x_axis_clickable
+
It indicates if the X axis allows to be clicked for navigating to the field +(if it’s a many2one field). True by default
+
y_axis_clickable
+
It indicates if the Y axis allows to be clicked for navigating to the field +(if it’s a many2one field). True by default
+
field_value
+
Show this field as value
+
show_row_totals
+
If field_value is a numeric field, it indicates if you want to calculate +row totals. True by default
+
show_column_totals
+
If field_value is a numeric field, it indicates if you want to calculate +column totals. True by default
+
field_att_<name>
+
Declare as many options prefixed with this string as you need for binding +a field value with an HTML node attribute (disabled, class, style…) +called as the <name> passed in the option.
+
+
+
+

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:

+
+<field name="task_ids" widget="x2many_2d_matrix" field_x_axis="project_id" field_y_axis="user_id" field_value="planned_hours" />
+
+

Note that all values in the matrix must exist, so you need to create them +previously if not present, but you can control visually the editability of +the fields in the matrix through field_att_disabled option with a control +field.

+
+
+

Known issues / Roadmap

+
    +
  • It would be worth trying to instantiate the proper field widget and let it render the input
  • +
  • Let the widget deal with the missing values of the full Cartesian product, +instead of being forced to pre-fill all the possible values.
  • +
  • If you pass values with an onchange, you need to overwrite the model’s method +onchange for making the widget work:
  • +
+
+@api.multi
+def onchange(self, values, field_name, field_onchange):
+    if "one2many_field" in field_onchange:
+        for sub in [<field_list>]:
+            field_onchange.setdefault("one2many_field." + sub, u"")
+    return super(model, self).onchange(values, field_name, field_onchange)
+
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Therp BV
  • +
  • Tecnativa
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

This module is part of the OCA/web project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ +