Introducción
En Odoo, los modelos son la plantilla que dicta cómo se guarda y organiza la información en la base de datos. Todo dato empresarial —desde pedidos de compra hasta facturas o movimientos de stock— se representa como registros dentro de modelos concretos.
Tener claro qué son y cómo funcionan los modelos es imprescindible tanto para desarrolladores como para consultores funcionales. Los modelos constituyen la columna vertebral de la arquitectura de datos en Odoo: definen campos, relaciones y la lógica que gobierna los registros.
Aquí nos centramos en un modelo fundamental: purchase.order. Si vas a desarrollar módulos a medida, conectar sistemas externos o diseñar flujos de aprovisionamiento, este modelo será uno de los que más vas a manejar.
¿Qué es el modelo purchase.order?
El modelo purchase.order recoge las solicitudes de propuesta (RFQ) y los pedidos de compra. Es el punto único donde se registra la intención de compra antes de que esa información genere albaranes, entradas de stock o facturas al proveedor.
El módulo de Compras usa este modelo como base. Un comprador crea una RFQ que aparece como un registro purchase.order en estado borrador; cuando el proveedor confirma o el comprador valida, el registro pasa a confirmado. El propio campo de estado mantiene el seguimiento del ciclo de vida, y en un único modelo conviven tanto RFQs como pedidos confirmados.
Otros módulos amplían purchase.order mediante herencia de modelos en Odoo. Inventario añade la lógica de recepciones y pickings; Contabilidad enlaza campos para las facturas proveedor; Fabricación puede generar pedidos a partir de una lista de materiales. Cada extensión añade lo necesario sin duplicar la estructura central.
Campos clave del modelo
A continuación tienes los campos más relevantes del modelo purchase.order. Comprenderlos te permitirá trabajar con pedidos de compra con seguridad y eficiencia.
1. name
Tipo: Char. Identificador del pedido (por ejemplo, PO00042). Normalmente se genera automáticamente y se muestra en vistas de lista y documentos. Es la referencia principal para localizar el pedido.
2. state
Tipo: Selection. Indica la fase del pedido. Valores habituales: draft (RFQ), sent (enviado al proveedor), to approve (esperando aprobación), purchase (confirmado), done (recibido y facturado), cancel (cancelado). El estado condiciona las acciones disponibles en la interfaz y la lógica de negocio.
3. partner_id
Tipo: Many2one (res.partner). El proveedor o suministrador. Campo obligatorio. Define la compañía o contacto proveedor asociado al pedido y se usa en toda la lógica relacionada con compras y reporting.
4. partner_ref
Tipo: Char. Referencia facilitada por el proveedor (su número de pedido). Se muestra en documentos y ayuda a conciliar recepciones y facturas con la referencia del proveedor.
5. date_order
Tipo: Datetime. Fecha del pedido: en borrador suele ser la fecha de creación; al confirmar se registra la fecha de confirmación. Se usa para informes, ordenación y como referencia de fechas esperadas en las líneas.
6. date_approve
Tipo: Datetime. Fecha de aprobación o confirmación. Se establece cuando el pedido pasa a estado purchase. Es de solo lectura y sirve en auditorías e informes.
7. order_line
Tipo: One2many (purchase.order.line). Las líneas del pedido. Cada línea incluye producto, cantidad, precio y los impuestos aplicables: son los detalles operativos del pedido.
8. amount_untaxed
Tipo: Float. Subtotal sin impuestos. Se calcula en función de las líneas del pedido. Se utiliza en presentación y análisis económicos.
9. amount_tax
Tipo: Float. Total de impuestos. Se computa a partir de los impuestos definidos en las líneas. Se muestra en el pedido y en la factura del proveedor.
10. amount_total
Tipo: Float. Importe total con impuestos. Es la cifra principal para facturación y reporting.
11. currency_id
Tipo: Many2one (res.currency). Moneda del pedido. Normalmente se hereda de la empresa o del proveedor. Todos los campos monetarios usan esta moneda.
12. origin
Tipo: Char. Documento origen. Se guarda la referencia cuando el pedido nace desde otro documento (por ejemplo, una venta en dropshipping o una orden de fabricación). Facilita la trazabilidad.
13. dest_address_id
Tipo: Many2one (res.partner). Dirección de entrega. Si no se especifica, suele usarse la dirección de la empresa. Es clave en dropshipping, cuando el proveedor envía directamente al cliente final.
14. priority
Tipo: Selection. Prioridad del pedido: Normal u Urgente. Sirve para ordenar y resaltar pedidos; los urgentes pueden tener tratamiento diferenciado en el flujo operativo.
15. invoice_status
Tipo: Selection. Estado de facturación: no (sin facturar), to invoice (por facturar), invoiced (facturado). Determina si está disponible la acción Crear Factura y guía el seguimiento contable.
16. invoice_count
Tipo: Integer. Número de facturas proveedor asociadas. Campo computado que facilita la navegación hasta las facturas vinculadas.
17. invoice_ids
Tipo: One2many (account.move). Facturas proveedor relacionadas. Enlaza compras con contabilidad y soporta procesos de conciliación y pago.
18. picking_ids
Tipo: One2many (stock.picking). Órdenes de entrega o recepciones asociadas. Solo aparecen cuando Inventario está instalado y permiten gestionar entradas y salidas de mercancía.
19. picking_count
Tipo: Integer. Número de pickings relacionados. Campo computado para mostrar y acceder a las recepciones asociadas al pedido.
20. create_date
Tipo: Datetime. Fecha y hora de creación del registro. Gestionado por Odoo automáticamente; útil en informes y auditorías.
21. write_date
Tipo: Datetime. Fecha y hora de la última modificación. También gestionado automáticamente y ayuda a saber cuándo se actualizó por última vez un pedido.
22. notes
Tipo: Text. Notas internas o condiciones. Suele imprimirse en el documento y sirve para instrucciones especiales al proveedor.
23. company_id
Tipo: Many2one (res.company). En entornos multiempresa, indica a qué compañía pertenece el pedido. Afecta visibilidad y reglas de acceso.
24. user_id
Tipo: Many2one (res.users). Usuario responsable o comprador asignado. Se utiliza en flujos de aprobación y para asignar actividades.
25. fiscal_position_id
Tipo: Many2one (account.fiscal.position). Posición fiscal para hacer mappings de impuestos según país o régimen fiscal del proveedor.
26. payment_term_id
Tipo: Many2one (account.payment.term). Plazo de pago (por ejemplo, 30 días, 50% por adelantado). Se aplica al crear la factura proveedor.
27. display_name
Tipo: Char. Nombre mostrado: combinación de la referencia del pedido y datos del proveedor. Aparece en campos many2one y en búsquedas; es de solo lectura.
28. active
Tipo: Boolean. Indicador de archivado (soft delete). Si es False, el pedido queda oculto en vistas por defecto; no se elimina físicamente para conservar el histórico.
Cómo se utiliza este modelo en los procesos de negocio
1. De RFQ a Pedido de compra
El comprador crea una RFQ en estado borrador, añade líneas y la envía al proveedor. Cuando el proveedor confirma o el comprador valida, el registro cambia a confirmado (purchase). A partir de ahí pueden generarse recepciones y facturas proveedor.
2. Recepción de proveedor
A la llegada de mercancía se crea una recepción (picking) desde el pedido. Los pickings quedan vinculados a purchase.order y las cantidades recibidas actualizan el stock; además, el coste del producto puede actualizarse según el precio de compra.
3. Factura al proveedor
Desde un pedido confirmado se genera la factura proveedor. Las líneas de la factura provienen de las líneas del pedido; condiciones como payment_term_id o fiscal_position_id se heredan del pedido y invoice_status refleja el progreso de facturación.
4. Dropshipping
Cuando una venta dispara una compra, el campo origin enlaza con la venta y dest_address_id se configura con la dirección del cliente para que el proveedor envíe directamente al consumidor. El modelo purchase.order actúa como puente entre ventas y compras.
5. Fabricación y MRP
Si una orden de fabricación requiere componentes externos, puede generar pedidos de compra para las materias primas. El campo origin referencia la orden de fabricación, integrando el proceso de procure-to-pay con el flujo de producción.
Cómo amplían los desarrolladores este modelo
Los desarrolladores amplían purchase.order siguiendo patrones propios de Odoo, siendo la herencia de modelos la vía principal para introducir cambios sin romper la base del sistema.
Herencia de modelos
Usa _inherit = 'purchase.order' para extender el modelo. Puedes agregar campos, redefinir métodos o añadir restricciones. Mantener las extensiones en un módulo separado facilita actualizaciones y evita tocar el core directamente.
Añadir campos
Declara nuevos campos en tu modelo heredado con el tipo adecuado: Char, Many2one, Boolean, Integer, Text, Selection, etc. Considera campos dependientes de compañía en entornos multiempresa para evitar inconsistencias.
Extensiones en Python
Sobrescribe métodos como button_confirm, create o write para insertar lógica personalizada, llamando a super() cuando sea necesario. Presta atención a campos computados y sus dependencias para que las actualizaciones se propaguen correctamente.
Odoo Studio
Odoo Studio permite añadir campos y vistas sin tocar código, ideal para personalizaciones rápidas. Para lógica compleja o proyectos de larga vida, es preferible un módulo a medida. El modelo purchase.order está accesible mediante XML-RPC y JSON-RPC para integraciones con sistemas externos.
Buenas prácticas
- Usa el estado correcto en cada fase del proceso. No te saltes estados ni actives atajos que omitan validaciones del flujo.
- Registra partner_ref cuando el proveedor facilite su propia referencia: facilita la conciliación entre facturas y recepciones.
- Rellena origin para mantener la trazabilidad del pedido: es vital en dropshipping y en procesos de fabricación enlazados.
- Para integraciones API, utiliza XML-RPC o JSON-RPC y mapea con cuidado los identificadores externos; presta atención a campos obligatorios y formatos de fecha/moneda.
- Cuando añadas campos personalizados, usa prefijos x_ o el prefijo de tu módulo para evitar colisiones con futuras versiones de Odoo.
Errores frecuentes
- Modificar pedidos confirmados sin comprobar el estado. Los pedidos confirmados tienen restricciones: en muchos casos lo correcto es crear un nuevo pedido o seguir el flujo de modificación previsto.
- Confundir partner_id y dest_address_id. partner_id identifica al proveedor; dest_address_id es la dirección donde se entregan los bienes (por ejemplo, la del cliente en dropshipping).
- Sobrescribir button_confirm sin llamar a super(). Esto puede romper compatibilidades con otros módulos o complicar futuras actualizaciones.
- Añadir campos obligatorios sin valores por defecto. Al actualizar o migrar, los registros existentes pueden fallar la validación y provocar errores en masa.
- Olvidar establecer currency_id en operaciones multi-moneda. Una moneda incorrecta ocasiona cálculos erróneos de coste y problemas en la facturación.
Conclusión
El modelo purchase.order es el núcleo del módulo de Compras en Odoo: guarda tanto RFQs como pedidos confirmados. Conocer sus campos y cómo se extiende te permitirá configurar, personalizar e integrar Odoo con seguridad.
Tanto si diseñas procesos de compra como si desarrollas módulos a medida, dominar purchase.order te ahorrará tiempo y reducirá riesgos operativos.
¿Necesitas ayuda con tu implementación de Odoo?
Dasolo acompaña a empresas en la implementación, personalización y optimización de Odoo. Nos especializamos en integraciones API y desarrollo sobre la arquitectura de datos de Odoo, con experiencia práctica en modelos como purchase.order.
Si necesitas apoyo con tu implementación de Odoo, desarrollo de módulos o integraciones, podemos ayudarte. Solicita una demo para comentar tu proyecto.