Introducción
En Odoo, los modelos son la plantilla que dicta cómo se guarda cada tipo de información en la base de datos. Todo dato empresarial —pedidos, facturas, movimientos de almacén— se organiza dentro de un modelo concreto para que la aplicación pueda leerlo, buscarlo y procesarlo.
Comprender los modelos de Odoo es imprescindible tanto para desarrolladores como para consultores funcionales. Son la columna vertebral de la arquitectura: definen campos, relaciones entre registros y la lógica de negocio que rige su comportamiento.
Este artículo se centra en uno de los modelos más relevantes para la logística: stock.move. Si diseñas módulos de almacén, sincronizas inventario con sistemas externos o configuras rutas de aprovisionamiento, acabarás trabajando con este modelo.
¿Qué es el modelo stock.move?
El modelo stock.move representa un movimiento concreto de inventario: la transferencia de una unidad de producto desde una ubicación origen hasta una ubicación destino. Cada vez que se desplaza mercancía —desde una estantería a un palé, entre almacenes o hacia un cliente— se genera un registro stock.move.
El módulo de Inventario emplea este modelo de forma transversal. Ventas, Compras, Fabricación y tiendas online crean o actualizan movimientos cuando se producen operaciones físicas: confirmar un albarán, recibir un pedido de proveedor o finalizar una orden de producción generan registros stock.move.
stock.move se define en el módulo stock y se puede ampliar desde otros módulos mediante herencia. Ventas añade enlaces a la línea de pedido, Compras enlaza la línea de pedido de compra y Fabricación añade la relación con la orden productiva: cada extensión aporta lo necesario sin duplicar la estructura base.
Campos clave del modelo
A continuación se describen los campos más útiles del modelo stock.move. Manejar bien estos atributos facilita la configuración, trazabilidad e integración de inventario.
1. name
Tipo: Char. Guarda la etiqueta o descripción del movimiento, normalmente compuesta por el producto y la cantidad. Es el texto que se muestra en listados y documentos y ayuda a identificar el movimiento rápidamente.
2. product_id
Tipo: Many2one (product.product). Producto afectado por el movimiento. Campo obligatorio: todo movimiento debe referenciar un producto para que Odoo pueda contabilizar cantidades y aplicar reglas de inventario.
3. product_uom
Tipo: Many2one (uom.uom). Unidad de medida usada para la cantidad. Requerida y habitualmente coincide con la UoM por defecto del producto; Odoo espera las cantidades expresadas en esta unidad.
4. product_uom_qty
Tipo: Float. Cantidad solicitada en la unidad del producto. Representa la demanda prevista. Una vez procesado el movimiento, quantity_done reflejará la cantidad realmente movida.
5. quantity
Tipo: Float. Campo de presentación o cálculo que muestra la cantidad; en vistas suele usarse para claridad. Puede coincidir con product_uom_qty o representar una conversión a otra unidad.
6. location_id
Tipo: Many2one (stock.location). Ubicación origen desde la que sale el producto. Es obligatoria. Para salidas suele ser el almacén; para entradas puede ser la ubicación del proveedor o de producción.
7. location_dest_id
Tipo: Many2one (stock.location). Ubicación destino a la que llega el producto. Obligatoria. En entradas será la ubicación de stock; en salidas puede ser la ubicación cliente o de baja.
8. picking_id
Tipo: Many2one (stock.picking). El albarán o documento que agrupa el movimiento: entrega, recepción o traslado interno. Las operaciones se presentan y manejan por picking.
9. picking_type_id
Tipo: Many2one (stock.picking.type). Tipo de operación: entrega, recepción o transferencia interna. Determina el flujo de trabajo y las localizaciones por defecto.
10. state
Tipo: Selection. Estado actual del movimiento: draft, waiting, confirmed, assigned, done, cancelled. Draft indica no confirmado; assigned significa que el stock está reservado; done es movimiento finalizado.
11. date
Tipo: Datetime. Fecha programada del movimiento, útil para planificación y priorización de operaciones dentro del almacén.
12. date_deadline
Tipo: Datetime. Fecha límite asociada al movimiento —por ejemplo, la fecha prometida al cliente— y que sirve para calcular urgencias y prioridades.
13. origin
Tipo: Char. Referencia al documento origen (número de pedido de venta, compra u orden de fabricación). Facilita rastrear de dónde procede el movimiento.
14. move_dest_id
Tipo: Many2one (stock.move). Enlaza con el movimiento destino en cadenas de movimientos. Cuando un movimiento alimenta a otro (por ejemplo, producción que da salida a una entrega), se usa este enlace para propagar información.
15. move_orig_ids
Tipo: One2many (stock.move). Movimientos origen que alimentan al actual. Es la inversa de move_dest_id y es útil para trazabilidad hacia atrás.
16. move_line_ids
Tipo: One2many (stock.move.line). Líneas del movimiento con detalle de lote, número de serie, ubicaciones exactas y cantidades por lotes. Se crean al reservar o procesar existencias.
17. partner_id
Tipo: Many2one (res.partner). El socio implicado: cliente en entregas o proveedor en recepciones. Se usa para direcciones, condiciones y reporting.
18. company_id
Tipo: Many2one (res.company). Indica a qué compañía pertenece el movimiento en entornos multiempresa; afecta visibilidad y reglas intercompañía.
19. quantity_done
Tipo: Float. Cantidad realmente procesada. Al validar una recogida o recepción, se actualiza este campo; el movimiento se considera done cuando quantity_done alcanza product_uom_qty.
20. reserved_availability
Tipo: Float. Cantidad que está reservada para este movimiento. Se rellena cuando el movimiento está en estado assigned y refleja la disponibilidad asegurada.
21. create_date
Tipo: Datetime. Fecha y hora de creación del registro, gestionada automáticamente por Odoo; útil para auditoría e informes históricos.
22. write_date
Tipo: Datetime. Fecha y hora de la última modificación, también gestionada automáticamente y necesaria para seguimiento de cambios.
23. sequence
Tipo: Integer. Orden de visualización dentro de un picking; los números más bajos se muestran antes y ayudan a organizar la ejecución.
24. priority
Tipo: Selection. Nivel de urgencia (por ejemplo, normal o urgente). Influyen en la planificación y permiten priorizar movimientos críticos.
25. description_picking
Tipo: Char. Nota descriptiva para el movimiento que aparece en el albarán; ideal para instrucciones especiales de manipulación.
26. reference
Tipo: Char. Referencia interna o código que puedes usar para mapear con sistemas externos o hacer seguimiento personalizado.
27. group_id
Tipo: Many2one (procurement.group). Agrupa movimientos relacionados por la misma compra o proceso (por ejemplo, todas las líneas de un pedido de venta). Facilita planificación y encadenado.
28. procure_method
Tipo: Selection. Determina el método de aprovisionamiento: make to stock (tomar stock existente) o make to order (provoca producción o compra).
29. sale_line_id
Tipo: Many2one (sale.order.line). Campo añadido por Ventas que enlaza el movimiento con la línea del pedido que lo generó, útil para trazabilidad y reporting comercial.
30. purchase_line_id
Tipo: Many2one (purchase.order.line). Campo añadido por Compras que conecta el movimiento con la línea de la orden de compra al recibir mercancía.
31. production_id
Tipo: Many2one (mrp.production). Añadido por Fabricación; vincula el movimiento a la orden de producción y ayuda a gestionar consumos y salidas de producto terminado.
32. active
Tipo: Boolean. Indicador de archivo lógico. Si está a False, el registro queda oculto por defecto pero no se elimina físicamente.
Cómo se usa este modelo en los procesos de negocio
1. Entrega al cliente
Al confirmar un pedido de venta, Odoo crea un stock.move por cada línea de producto: la ubicación origen es el almacén y la destino el cliente. Esos movimientos se agrupan en un picking (albarán). Cuando se preparan y envían los productos, se actualiza quantity_done y el estado pasa a done.
2. Recepción de proveedor
Al confirmar una orden de compra se generan movimientos entrantes: la ubicación origen puede representar al proveedor y la destino es el almacén. Se agrupan en un recibo; al recibir y validar la mercancía se actualiza quantity_done.
3. Traslado interno
Los traslados entre ubicaciones o almacenes crean movimientos donde una ubicación es origen y otra destino. Estos sirven para reposiciones, equilibrar stock entre almacenes o gestionar operaciones multiubicación.
4. Fabricación
Las órdenes de fabricación generan movimientos de dos tipos: consumo de materias primas (del stock a producción) y salida de productos terminados (de producción a stock). production_id enlaza ambos tipos y move_dest_id facilita encadenar la salida productiva con entregas posteriores.
5. Devoluciones y baja (scrap)
Las devoluciones de cliente se registran como movimientos inversos y las operaciones de scrap mueven mercancía a una ubicación de desecho. El mismo modelo stock.move cubre todos estos casos; picking_type_id define el flujo específico.
Cómo lo amplían los desarrolladores
Los desarrolladores amplían stock.move con varios patrones, siendo la herencia de modelos de Odoo el método principal.
Herencia de modelo
Emplea _inherit = 'stock.move' para añadir campos, validar o anular métodos. Mantener las extensiones en módulos separados facilita actualizaciones y evita tocar el núcleo.
Agregar campos
Declara nuevos campos en tu modelo heredado usando los tipos adecuados (Char, Many2one, Boolean, Integer, Text, Selection). En escenarios multiempresa valora campos dependientes de compañía. Extensiones típicas son números de seguimiento personalizados, referencias de transportista o atributos de lote.
Extensiones en Python
Sobrescribe métodos como _action_done, _action_assign o _action_cancel para incorporar lógica adicional, llamando a super() para mantener el comportamiento base. Precaución: las actualizaciones de inventario y el encadenado de movimientos son sensibles a cambios indebidos.
Odoo Studio
Odoo Studio permite añadir campos y pequeñas personalizaciones sin programar, útil para cambios rápidos en formularios. Para lógica compleja o flujos, los módulos personalizados son más robustos y mantenibles.
Buenas prácticas
- Asegúrate siempre de establecer correctamente location_id y location_dest_id: ubicaciones equivocadas generan saldos erróneos y problemas de inventario.
- Usa picking_id para agrupar movimientos relacionados; no crees movimientos sueltos cuando forman parte de una misma transferencia.
- Si integras con APIs externas, utiliza XML-RPC o JSON-RPC. stock.move está expuesto y debes mapear identificadores externos con cuidado para evitar incoherencias.
- Para campos personalizados, usa prefijos como x_ o el prefijo de tu módulo para reducir riesgos de colisión en futuras versiones de Odoo.
- Utiliza move_dest_id y move_orig_ids para mantener trazabilidad entre movimientos encadenados; al crear movimientos por código, establece estos vínculos correctamente.
- Ten en cuenta la diferencia entre quantity_done y product_uom_qty: las entregas parciales son válidas y la validación debe contemplarlas.
Errores frecuentes
- Crear movimientos con tipos de ubicación incompatibles. El origen y destino deben tener sentido operativo (por ejemplo, no pueden ser ambas ubicaciones de cliente).
- Modificar product_uom_qty después de haber creado move lines. Cambiar cantidades en caliente puede provocar inconsistencias; en muchos casos es preferible cancelar y recrear el movimiento.
- Olvidar fijar origin. Sin referencia al documento origen resulta difícil trazar el movimiento hasta su pedido o fabricación inicial.
- Sobrescribir _action_done sin llamar a super(). Omitir la llamada al método base puede romper actualizaciones de inventario y afectar a otros módulos.
- Crear movimientos directamente saltándose el workflow (por ejemplo, sin pasar por stock.picking). Esto puede romper reservas, asignaciones y el flujo estándar.
- Ignorar move_dest_id al dividir o fusionar movimientos. Los movimientos encadenados pueden quedarse huérfanos si no se mantienen las referencias.
Conclusión
stock.move es una pieza central del inventario en Odoo: registra cada movimiento de mercancía entre ubicaciones. Conocer sus campos y cómo los módulos lo amplían te permitirá configurar, personalizar e integrar Odoo con menos errores.
Tanto si eres consultor mapeando procesos de almacén como desarrollador creando módulos, dominar stock.move te ahorrará tiempo y problemas operativos.
¿Necesitas ayuda con tu implementación de Odoo?
Dasolo ayuda a empresas a implantar, personalizar y optimizar Odoo. Estamos especializados en integraciones por API y desarrollo a medida, con experiencia en la arquitectura de datos y modelos como stock.move.
Si necesitas soporte en tu implementación de Odoo, desarrollos a medida o integraciones, podemos acompañarte en el proyecto. Reserva una demo para hablar de tu proyecto.