OdooWiki OCA HUB

2D matrix for x2many fields

web_widget_x2many_2d_matrix folder_open OCA/web open_in_new
Hidden/Dependency Licencia: AGPL-3

Este módulo permite mostrar un campo x2many con 3-tuplas (\$x_value, \$y_value, \$value) en una tabla

| | \$x_value1 | \$x_value2 | |------------|--------------|--------------| | \$y_value1 | \$value(1/1) | \$value(2/1) | | \$y_value2 | \$value(1/2) | \$value(2/2) |

donde value(n/n) es editable.

Un caso de uso de ejemplo sería: Seleccionar algunos proyectos y algunos empleados para que un gerente pueda rellenar fácilmente las planned_hours para una tarea por empleado. El resultado podría verse así:

Lo bueno de esto es que tienes una cantidad arbitraria de columnas con este widget, intentar conseguir esto en las listas x2many estándar implica algunos trucos bastante feos.

Traducción automática al español (DeepSeek) de la descripción original de OCA, que está en inglés.

auto_awesome Qué hace este módulo

Generado por IA a partir del código · Odoo 19.0

Añade un nuevo widget de campo que muestra una lista de registros relacionados como una matriz 2D editable, con un campo en el eje horizontal, uno en el eje vertical y un campo de valor en cada celda.

Este módulo proporciona un nuevo widget de campo llamado x2many_2d_matrix que se puede usar en cualquier campo x2many (por ejemplo, una lista de usuarios en un grupo). En lugar de mostrar los registros como una lista normal, los organiza en una tabla: los valores de un campo se convierten en las columnas, los valores de otro campo se convierten en las filas, y un tercer campo se muestra y se edita en cada celda.

  • El widget se configura en la vista con tres atributos: field_x_axis, field_y_axis y field_value. El campo de valor puede ser de tipo integer, float, monetary, char, boolean, selection o many2one.
  • Cuando el campo de valor es numérico, el widget puede mostrar totales de fila, totales de columna y un total general. Estos totales se muestran por defecto, pero se pueden desactivar con show_row_totals y show_column_totals.
  • Si el campo del eje x o y es un many2one, las etiquetas de los ejes se pueden hacer clicables para abrir el registro relacionado, usando x_axis_clickable y y_axis_clickable.
  • El widget respeta la configuración de domain, required y readonly definida en los campos dentro de la vista de lista incrustada. Por ejemplo, un campo de valor puede ser required solo para ciertas filas o readonly para ciertos usuarios.
  • Si no hay registros, se muestra el mensaje "Nothing to display.".

El módulo solo añade un widget de frontend; no crea nuevos modelos ni menús. Incluye una vista de demostración en el formulario de Grupos (res.groups) que muestra varios ejemplos del widget con diferentes tipos de campo.

Texto generado por IA (DeepSeek) al leer el código de la versión 19.0 en GitHub; puede contener errores, así que verifícalo en el código antes de decidir. Ver el código en GitHub

Disponibilidad por versión

Revisado: 2026-11-03
Confirmado (verificado en repositorio y rama) Estimado (sin verificar) Sin información

Estado de confirmación: 8 confirmadas, 1 sin información de 9 versiones.

terminal Instalación y uso

Documentación de OCA · Odoo 19.0

Use este widget diciendo:

Esto asume que my_field se refiere a un modelo con los campos x, y y value. Si sus campos tienen nombres diferentes, pase los nombres correctos como atributos:

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

Puede pasar los siguientes parámetros:

field_x_axis El campo que indica el valor x de un punto

field_y_axis El campo que indica el valor y de un punto

field_value Mostrar este campo como valor

show_row_totals Si field_value es un campo numérico, indica si desea calcular los totales de fila. True por defecto

show_column_totals Si field_value es un campo numérico, indica si desea calcular los totales de columna. True por defecto

x_axis_clickable Si el campo del eje x es un campo many2one, renderiza los valores como enlaces al registro en cuestión

y_axis_clickable Si el campo del eje y es un campo many2one, renderiza los valores como enlaces al registro en cuestión

Para el campo value, puede establecer cualquier atributo que establecería en una vista de lista normal, es decir, si su campo value es un campo many2one y desea deshabilitar la creación de registros a través de este campo, escribiría

<field name="my_field3" options="{'no_create': true}"/>

o si desea tener un domain o context personalizado

<field name="my_field3" domain="[('some_field', '=', my_field1)]" context="{'default_some_field': my_field1}" />

Tenga en cuenta que para poder referirse a otros campos distintos de los usados como coordenadas o valor, debe agregarlos dentro del nodo list.

Ejemplo

Necesita una estructura de datos ya rellenada con valores. Supongamos que queremos usar este widget en un asistente que permite al usuario introducir las horas planificadas para una tarea por proyecto por usuario. En este caso, podemos usar project.task como nuestro modelo de datos y apuntar a él desde nuestro asistente. La parte crucial es que rellenamos el campo en la función default:

from odoo import fields, models

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, {
                'name': 'Sample task name',
                'project_id': p.id,
                'user_id': u.id,
                'planned_hours': 0,
                'message_needaction': False,
                'date_deadline': fields.Date.today(),
            })
            # 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)

Ahora en nuestro asistente, podemos usar:

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

Traducción automática al español (DeepSeek) de la documentación original de OCA; los comandos y el código no se traducen. Sin información verificada en OCA: Instalación, Configuración.

info

Datos importados de GitHub: esta ficha refleja la última revisión del catálogo, no una consulta en directo. Verifica siempre en la documentación del módulo y en staging antes de instalar en producción.