Agrupando las líneas de las órdenes de compra

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

A veces el departamento de Compras necesita que se agrupen las líneas de los órdenes de compra (más de una vez le enviaron órdenes de compra con centenares de líneas a un proveedor, y las mismas se podrían haber reducido a diez o veinte líneas).

Mas alla de los motivos, hicimos un módulo que muestra como agrupar líneas de órdenes de compra. Este módulo también muestra el patrón sobre como crear modelos en base a vistas de la base de datos (principio ilustrado en el post Creando Consultas en Odoo).

La idea es la siguiente. Vamos a agrupar las líneas de los pedidos de compra en base a los siguientes campos: producto y unidad de medida. Y se sumarizaran las cantidades, precios totales y subtotales, y para el precio unitario se obtendrá un promedio. Esto lo hacemos mediante la siguiente sentencia SQL:

select order_id,product_id,product_uom,max(id) as id, 
sum(product_qty) as product_qty,
avg(price_unit) as price_unit,
sum(price_subtotal) as price_subtotal,
sum(price_total) as price_total
from purchase_order_line group by 1,2,3

Obtenemos el máximo del ID debido a que todas las líneas que se muestran en Odoo necesitan tener un ID único. 

Bien, y la vista la mapeamos a un nuevo modelo en Odoo llamado purchase.order.group.lines. Este objeto al inicializarse no crea una tabla y crea la vista SQL que necesitamos

class PurchaseOrderGroupLines(models.Model):
_name = "purchase.order.group.lines"
_description = "Purchase Order Group Lines"
_auto = False

order_id = fields.Many2one('purchase.order','Purchase Order')
product_id = fields.Many2one('product.product','Producto')
product_uom = fields.Many2one('product.product','Producto')
product_qty = fields.Float('Cantidad')
price_unit = fields.Float('Ptice Unit')
price_subtotal = fields.Float('Price Subtotal')
price_total = fields.Float('Price Total')

def init(self):
tools.drop_view_if_exists(self._cr, self._table)
query = """
select order_id,product_id,product_uom,max(id) as id, sum(product_qty) as product_qty,
avg(price_unit) as price_unit, sum(price_subtotal) as price_subtotal, sum(price_total) as price_total
from purchase_order_line group by 1,2,3
"""
self._cr.execute("""CREATE or REPLACE VIEW %s as (%s)""" % (self._table, query))

Y relacionamos el modelo purchase.order con el modelo que acabamos de crear


class PurchaseOrder(models.Model):
_inherit = 'purchase.order'

group_line_ids = fields.One2many(
​comodel_name='purchase.order.group.lines',
​inverse_name='order_id')


Por último, utilizando xpath agregamos un nuevo tab al pedido de compras con los datos agrupados


<record id="purchase_order_group_lines_form" model="ir.ui.view">
<field name="name">purchase.order.group.lines.form</field>
<field name="model">purchase.order</field>
<field name="inherit_id" ref="purchase.purchase_order_form"></field>
<field name="arch" type="xml">
<xpath expr="//notebook" position="inside">
<page string="Grouped lines">
<field name="group_line_ids">
<tree>
<field name="product_id" />
<field name="product_uom" />
<field name="price_unit" />
<field name="product_qty" />
<field name="price_subtotal" />
<field name="price_total" />
</tree>
</field>
</page>
</xpath>
</field>
</record>

Este es el resultado, para las siguientes líneas del pedido de compras


Tenemos los siguientes items agrupados


El módulo lo pueden encontrar en nuestro repositorio. Este módulo le falta trabajo aún, por ejemplo le falta agregar las secuencias para imprimr el número de línea, campos adicionales para poder reemplazar las líneas en el reporte de las órdenes de compras, y ademas agregar las líneas de las notas. Pero ilustra el principio por el cual se pueden agrupar líneas de transacciones.

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