Listas de materiales y recursividad

Gustavo Orrillo
- 17/06/2022 - 2 min. de lectura

Las listas de materiales son estructuras jerárquicas, en las cuales hay componentes padres (por lo general producto final y productos semi-elaborados) y componentes hijos (conocido como materia prima). En el mundo de Odoo; cada producto final o producto semi-elaborado tiene asociado una lista de materiales y debe ser manufacturado. Cada componente que es materia prima por lo general es comprado.


Y hay muchas veces en las cuales necesitamos realizar cálculos (o realizar operaciones) con cada uno de sus componentes. Por ejemplo calcular el costo total de la lista de materiales (en USD; un pedido muy recurrente estos días anda a saber porqué). O calcular el lead-time total de la lista de materiales. Para ello se requiere leer cada uno de los componentes de la lista de materiales, ya sea semi-elaborado o materia prima.

Es por eso que vamos a hablar de recursividad en este post, y dar un ejemplo de como se aplica en Odoo. Nada de ejemplos de recursividad de factoriales ni nada por el estilo. Vamos a ver un ejemplo usando el ORM de Odoo y como se navega cada uno de los componentes de la lista de materiales. Vamos a utilizar el módulo mrp_utils, del cual hablamos meses atras.

Bueno, vamos a ver en el código el ejemplo de recursividad. Supongamos que por algún motivo de negocio extraño necesitamos sumar los IDs de cada uno de las materias primas que componen nuestra lista de materiales. Y con esa suma de IDs actualizar un campo integer. Para ello podemos usar el siguiente código:

class MrpBom(models.Model):
    _inherit = 'mrp.bom'

    def _get_bom_products(self, value=0):
        for bom_line in self.bom_line_ids:
            if not bom_line.product_id.bom_ids:
                value = value + bom_line.product_id.id
            else:
                new_bom = bom_line.product_id.bom_ids[0]
                value = new_bom._get_bom_products(value)
        return value

    def get_bom_products(self):
        self.res_get_bom_products = self._get_bom_products()

Aca tenemos el método get_bom_products que podría ser llamada por un botón, o por medio de un campo computado. Y esta función por su parte llama el método _get_bom_products. En esta función, se recorre cada uno de los componentes de la lista de materiales. Y si cada componente tiene asociada una lista de materiales (indicando que es un semi-elaborado) cambia la lista de materiales donde está trabajando (ese es el truco) y vuelve a llamar a la función _get_bom_products. Caso contrario, retorna el valor que se le pasa como parámetro (como indica la literatura sobre recursividad).

Bueno, el ejemplo que acabo de brindar se puede extender a múltiples casos. Como para el reemplazo de materiales en listas de materiales (como lo hace el módulo mrp_utils), O el cálculo de los costos o lead-times. Sus usos son infinitos, por eso quería compartirlo.

Acerca de:

Gustavo Orrillo

Passionate about programming, he has implemented Odoo for different types of businesses since 2010. In Moldeo Interactive he is a founding Partner and Programmer; In addition to writing on the Blog about different topics related to the developments he makes.