Listando números de serie e inventarios por atributos de los productos

29 de julio de 2023 por
Gustavo Orrillo
| Sin comentarios aún
 

Este post extiendo lo que hablamos en el post, "Productos y Variantes en Odoo". A menos ​que uno no se encuentre en un ambiente de e-commerce (o en su caso, MercadoLibre o Tiendanube) jamás se deben usar los atributos de los productos. 

La realidad es; la funcionalidad de variantes es buena para cuando no se requiere intervención de un desarrollador y no se necesita customización. Ahora trabajamos con clientes que administran miles de productos para la venta y ahí necesitamos poder listar y filtrar los números de serie e inventarios por los atributos del producto. Hacer esto con la funcionalidad de las variantes es muy dificil (por no decir imposible).

Ahora para lograr eso; lo primero que debemos hacer es agregar los campos que necesitamos al modelo product.product. Supongamos que tenemos un modelo llamado rubro (product.rubro) y dos atributos llamados ancho y espesor. Los agregamos al producto de la siguiente manera:


class ProductProduct(models.Model):
_inherit = 'product.product'

rubro_id = fields.Many2one('product.rubro','Rubro')
ancho = fields.Float('Ancho')
espesor = fields.Float('Espesor')


Y vamos a necesitar listar o filtrar los números de serie (modelo stock.production.lot) e inventarios por dichos atributo. Entonces para ello vamos a tener que agregar dichos campos en ambos modelos y hacerlos computados. Estos campos deben ser almacenados (atributo store=True) debito a que el persistir dichos valores, es lo que nos permiten a posterioridad no solo filtrar por dichos campos sino ademas agruparlos y generar vistas pivot. 

Como se hace? A continuación el código para el inventario (modelo stock.quant)

class StockQuant(models.Model):
_inherit = 'stock.quant'

@api.depends('product_id')
def _compute_product_fields(self):
for rec in self:
if rec.product_id:
rec.espesor = rec.product_id.espesor
rec.rubro_id = rec.product_id.rubro_id.id
rec.ancho = rec.product_id.ancho
else:
rec.espesor = None
rec.rubro_id = None
rec.ancho = None

espesor = fields.Float('Espesor',
​compute=_compute_product_fields,store=True)
rubro_id = fields.Many2one('product.rubros','Rubros',
​compute=_compute_product_fields,store=True)
ancho = fields.Float('Ancho',store=True

Lo que hace esto es al actualizarse el campo producto en la línea de inventario (que Odoo mantiene automáticamente), se actualizan los campos computados de espesor, ancho y rubro. Otra opción por un tema de performance es hacerlo mediante un trigger de PostgreSQL, ya haremos eso en un post en los próximos días.

Ahora agregaremos un menú de la lista de inventario por estos campos, para que el usuario los pueda consultar.

<record id="cre_view_stock_quants_tree" model="ir.ui.view">
<field name="name">cre.stock.quants.tree</field>
<field name="model">stock.quant</field>
<field name="arch" type="xml">
<tree edit="0" create="0" delete="0">
<field name="location_id" />
<field name="product_id" />
<field name="lot_id" />
<field name="rubro_id" optional="show"/>
<field name="espesor" optional="show"/>
<field name="ancho" optional="show"/>
<field name="quantity" />
<field name="product_uom_id"/>
</tree>
</field>
</record>

<record id="action_view_cre_stock_quant" model="ir.actions.act_window">
<field name="name">Inventarios Paquetes</field>
<field name="res_model">stock.quant</field>
<field name="view_mode">tree,pivot</field>
<field name="view_id" ref="my_module.cre_view_stock_quants_tree"></field>
</record>

<menuitem id="menu_cre_stock_quant"
name="Inventarios Blog"
sequence="100"
parent="stock.menu_stock_inventory_control"
action="action_view_cre_stock_quant"/>

Y veamos como queda la vista tipo lista (tree view)


Y tipo pivot


Los cambios anteriormente descriptos también se pueden aplicar a los números de serie (modelo stock.production.lot) u otros objetos (por ejemplo, stock.move.line). Es posible que este método levante un grito en el cielo en los teóricos académicos que ven un sacrilegio que se violen las formas normales con esta des-normalización. Pero es un grito poco pragmático (y además no conocen las prácticas habituales de business-intelligence). Los campos computados son una buena y rápida manera de des-normalizar la información en forma seguro, y agregar mucha funcionalidad al sistema (mejorando de paso la experiencia del usuario).

Por último, vamos a hacer lo mismo en un futuro pero con triggers. Los campos computados son maravillosos, pero a nivel performance pueden llegar a darnos más de un dolor de cabeza.


Gustavo Orrillo 29 de julio de 2023
Compartir
Archivar
Identificarse dejar un comentario