Desde junio del 2014, cuando Odoo SA no solo cambió el nombre de OpenERP a Odoo sino además introdujo una nueva API; Odoo permite operaciones sobre sus recordsets (algo muy común con la librería pandas).
Un recordset es un conjunto de registros de un modelo, puede ser un registro o muchos. Y uno puede aplicar tres operaciones sobre los recordsets en Odoo: filtered, sorted y mapped. En este post explicaremos las dos primeras operaciones (filtered y sorted) y a modo de ejemplo veremos como se usaron en la localización argentina en el IVA Digital (donde se usa extensivamente).
Que es un recordset?
Un recordset es un conjunto de objetos en Odoo. Puede ser por ejemplo las líneas de impuestos asociadas a las facturas,:
move_tax_ids = inv.move_tax_ids
Esto devuelve una lista de objetos del modelo account.move.tax. Algo lindo de los mismos, pueden ser iterados. El tipo de campo one2many es por definición un recordset.
filtered
En base a una función lambda filtra los contenidos de un recordset. Similar a un search pero mucho más digerible. Por ejemplo en el IVA Digital podemos ver esta técnica cuando queremos iterar un recordset de los impuestos de tipo IVA que están relacionados con una factura:
for move_tax in inv.move_tax_ids.filtered(lambda l: l.tax_id.tax_group_id.tax_type == 'vat'):
En este ejemplo recorremos cada uno de los impuestos cuyo grupo de impuesto es del tipo IVA. Sobre estos resultados podemos aplicar operaciones. Por ejemplo, supongamos que queremos conocer la cantidad de alícuotas de IVA que hay en una factura
cantidad = len(inv.move_tax_ids.filtered(lambda l: l.tax_id.tax_group_id.tax_type == 'vat'))
mapped
De un recorset permite leer una lista de campos (o el resultado de una función). Por ejemplo, necesitamos sumar los montos de los impuestos de IIBB de una factura
perception_amount = sum(inv.move_tax_ids.\
filtered(lambda l: l.tax_id.tax_group_id.tax_type == 'withholdings' and l.tax_id.tax_group_id.l10n_ar_tribute_afip_code in ['07']).\
mapped('tax_amount'))
sorted
Tambien existe otro método denomiado sorted que nos permite ordenar un recordset (por ejemplo, si queremos ordenar las alicuotas en base al código de la alícuota)
alicuotas = inv.move_tax_ids.filtered(lambda l: l.tax_id.tax_group_id.tax_type == 'vat').sorted(lambda l: l.tax_id.tax_group_id.l10n_ar_vat_afip_code)
Conclusión
Las operaciones sobre los recordsets son herramientas muy poderosas de programación en Odoo. Uno debe aprenderlas porque reducen en forma notoria la cantidad de código y la posibilidad de errores.