Introducción
En Odoo, los modelos definen cómo se estructura y almacena la información en la base de datos. Cada pieza de datos empresariales con la que trabajas, desde pedidos de venta hasta facturas y contactos, reside en un modelo.
Entender los modelos de Odoo es esencial tanto para desarrolladores como para consultores funcionales. Los modelos son la base de la arquitectura de datos de Odoo. Definen campos, relaciones y lógica empresarial.
Este artículo se centra en uno de los modelos más importantes del módulo de Ventas: sale.order.line. Ya sea que estés construyendo módulos personalizados, integrando sistemas externos o configurando flujos de trabajo de precios, trabajarás con este modelo.
¿Qué es el modelo sale.order.line?
El modelo sale.order.line representa los artículos individuales en una cotización o pedido de venta en Odoo. Cada línea corresponde típicamente a un producto, con información de cantidad, precio e impuestos.
Este modelo en Odoo es utilizado por el módulo de Ventas (sale). Hereda de analytic.mixin para el seguimiento de costos de proyectos e integración de hojas de tiempo. Cuando añades un producto a una cotización, estás creando un registro de sale.order.line.
El modelo está definido en el módulo de venta. Otros módulos lo extienden a través de la herencia de modelos de Odoo. Por ejemplo, sale_stock añade campos relacionados con la entrega. sale_margin añade cálculos de margen. Cada módulo añade lo que necesita sin duplicar la estructura central.
Campos clave en el modelo
Aquí están los campos más importantes de Odoo en el modelo sale.order.line. Entender estos te ayudará a trabajar de manera efectiva con cotizaciones y pedidos de venta.
1. order_id
Tipo: Many2one (sale.order). Requerido. Referencia al pedido de venta padre. Este campo vincula cada línea a su padre. Las líneas se eliminan cuando se elimina el pedido (cascada).
2. sequence
Tipo: Integer. Predeterminado 10. Controla el orden de visualización de las líneas en el pedido. Se utiliza para ordenar secciones, notas y líneas de productos.
3. company_id
Tipo: Many2one (res.company). Relacionado desde order_id. Utilizado para reglas de múltiples empresas y control de acceso.
4. currency_id
Tipo: Many2one (res.currency). Relacionado desde order_id. Utilizado para todos los campos monetarios en la línea. Asegura la moneda correcta para la fijación de precios.
5. order_partner_id
Tipo: Many2one (res.partner). Relacionado desde order_id. El cliente. Utilizado para la lista de precios y las reglas fiscales.
6. salesman_id
Tipo: Many2one (res.users). Relacionado desde order_id. El vendedor. Utilizado para comisiones e informes.
7. state
Tipo: Selección. Relacionado desde order_id. Estado del pedido (borrador, enviado, venta, hecho, cancelado). Determina qué campos son editables.
8. display_type
Tipo: Selección. Valores: line_section o line_note. Cuando se establece, la línea es un encabezado de sección o una nota, no una línea de producto. Los campos del producto están vacíos.
9. is_downpayment
Tipo: Booleano. Indica si la línea es un anticipo. Los anticipos se facturan por separado.
10. is_expense
Tipo: Booleano. Verdadero cuando la línea proviene de un gasto o factura de proveedor. Utilizado para el seguimiento de costos del proyecto.
11. product_id
Tipo: Many2one (product.product). El producto que se vende. El dominio se restringe a productos vendibles. Requerido para las líneas de producto.
12. product_template_id
Tipo: Many2one (product.template). Computado a partir de product_id. Utilizado por el configurador de productos para la selección de variantes.
13. name
Tipo: Texto. La descripción de la línea. Computada a partir de atributos de producto y personalizados. Incluye detalles de la variante cuando sea aplicable.
14. product_uom_qty
Tipo: Flotante. Requerido. La cantidad ordenada. Por defecto 1.0. Puede estar determinada por el embalaje.
15. product_uom
Tipo: Many2one (uom.uom). Unidad de medida. Por defecto del producto. Utilizado para cantidad y precios.
16. tax_id
Tipo: Many2many (account.tax). Impuestos aplicados a la línea. Computado a partir del producto y la posición fiscal.
17. price_unit
Tipo: Flotante. Requerido. Precio unitario por producto_uom. Computado a partir de la lista de precios o del producto. Puede ser sobrescrito manualmente.
18. discount
Tipo: Flotante. Porcentaje de descuento. Aplicado al price_unit antes de impuestos.
19. price_subtotal
Tipo: Monetario. Subtotal antes de impuestos. Computado a partir de la cantidad, el precio unitario y el descuento.
20. price_tax
Tipo: Flotante. Monto total de impuestos. Computado a partir de price_subtotal y tax_id.
21. price_total
Tipo: Monetario. Total incluyendo impuestos. La cantidad principal para la facturación.
22. product_packaging_id
Tipo: Many2one (product.packaging). Embalaje opcional (por ejemplo, caja de 12). Cuando se establece, la cantidad puede ser determinada por el embalaje.
23. customer_lead
Tipo: Flotante. Tiempo de entrega en días. Días entre la confirmación del pedido y el envío. Utilizado para el cálculo de la fecha de entrega.
24. qty_delivered
Tipo: Flotante. Cantidad entregada. Actualizada por movimientos de stock o manualmente. Utilizada para la facturación parcial.
25. qty_invoiced
Tipo: Flotante. Cantidad ya facturada. Computada a partir de las líneas de factura.
26. qty_to_invoice
Tipo: Flotante. Cantidad restante por facturar. Computada a partir de qty_delivered y qty_invoiced.
27. invoice_status
Tipo: Selección. Valores: upselling, facturado, por facturar, no. Indica el estado de facturación de la línea.
28. invoice_lines
Tipo: Many2many (account.move.line). Enlaces a las líneas de factura creadas a partir de esta línea de venta. Utilizado para la trazabilidad.
29. create_date
Tipo: Fecha y hora. Cuándo se creó el registro. Gestionado automáticamente por Odoo.
30. write_date
Tipo: Fecha y hora. Cuándo se modificó por última vez el registro. Utilizado para auditoría.
Cómo se utiliza este modelo en los flujos de trabajo empresariales
1. Cotización y Pedido de Venta
Cuando un vendedor crea una cotización, añade productos. Cada producto se convierte en una sale.order.line. Las líneas muestran cantidad, precio, descuento y total. El pedido se confirma cuando el cliente acepta.
2. Lista de Precios y Descuentos
Las listas de precios se aplican por línea. Los campos price_unit y discount se calculan a partir de las reglas de la lista de precios. Los descuentos por volumen o los precios específicos para clientes se gestionan aquí.
3. Entrega y Facturación
Cuando se entrega el stock, qty_delivered se actualiza. La facturación se puede realizar por entrega o de una vez. El campo invoice_status guía al usuario sobre lo que queda por facturar.
4. Proyecto y Servicios
Para productos de servicio, las líneas se vinculan a tareas de proyecto y hojas de tiempo. La herencia analytic.mixin permite el seguimiento de costos por proyecto.
5. Comercio Electrónico y Portal
Los visitantes del sitio web añaden productos al carrito. Cada línea del carrito se convierte en una sale.order.line cuando se crea el pedido. El configurador de productos utiliza product_template_id y atributos personalizados.
Cómo los desarrolladores extienden este modelo
Los desarrolladores extienden sale.order.line utilizando varios patrones. La herencia de modelos de Odoo es el principal mecanismo.
Herencia de Modelos
Utiliza _inherit = 'sale.order.line' para extender el modelo. Agrega nuevos campos, anula métodos o añade restricciones. El modelo heredado en Odoo mantiene tus cambios en un módulo separado para facilitar las actualizaciones.
Añadiendo Campos
Define nuevos campos de Odoo en tu modelo heredado. Utiliza el tipo de campo correcto: Char, Many2one, Boolean, Integer, Text, Selection. Considera campos dependientes de la empresa para multi-empresa.
Extensiones de Python
Anula _compute_price_unit, _compute_price_subtotal, o crea/escribe para añadir lógica. Utiliza super() para llamar al original. Ten cuidado con los campos computados y sus dependencias.
Odoo Studio
Odoo Studio te permite añadir campos sin código. Es bueno para personalizaciones rápidas. Para lógica compleja o actualizaciones, los módulos personalizados son más mantenibles.
Mejores prácticas
- Utiliza display_type para secciones y notas en lugar de líneas de productos falsas. Esto mantiene los informes limpios.
- Al construir integraciones de API, crea líneas a través del order_id. Utiliza el campo order_line_ids en sale.order con el formato de comando correcto.
- Respeta las restricciones de SQL. Una línea de producto debe tener product_id y product_uom. Una sección o nota debe tener display_type.
- Para precios personalizados, utiliza reglas de lista de precios cuando sea posible. Sobrescribe los métodos de cálculo solo cuando necesites lógica no soportada por las listas de precios.
- Para campos personalizados, utiliza el prefijo
x_o un prefijo de módulo para evitar conflictos con futuras versiones de Odoo.
Errores comunes
- Creando líneas sin order_id. El campo es obligatorio. Siempre crea líneas en el contexto de un pedido.
- Confundir product_id y product_template_id. Para líneas de producto, establece product_id. Para flujos de configurador, utiliza product_template_id para seleccionar una variante.
- Modificar price_unit o discount después de la facturación. Una vez que qty_invoiced es mayor que cero, los cambios de precio pueden causar inconsistencias.
- Sobrescribir métodos centrales sin llamar a super(). Esto puede romper otros módulos o futuras actualizaciones.
- Olvidar establecer display_type para líneas de sección o nota. Sin ello, la línea se trata como una línea de producto y fallará la validación.
Conclusión
El modelo sale.order.line es central para Odoo Sales. Almacena cada línea de producto en cotizaciones y pedidos. Comprender sus campos y cómo los módulos lo extienden te ayudará a configurar, personalizar e integrar Odoo de manera efectiva.
Ya seas un consultor funcional mapeando procesos de negocio o un desarrollador construyendo módulos personalizados, un sólido entendimiento de sale.order.line te ahorrará tiempo y evitará errores.
¿Necesitas ayuda con tu implementación de Odoo?
Dasolo ayuda a las empresas a implementar, personalizar y optimizar Odoo. Nos especializamos en integraciones de API y desarrollo de Odoo. Nuestro equipo tiene una profunda experiencia con la arquitectura de datos de Odoo y modelos como sale.order.line.
Si necesita ayuda con su implementación de Odoo, módulos personalizados o integraciones, estamos aquí para ayudarle. Reserve una demostración para discutir su proyecto.