Pregunta de origen (entrevista / cuestionario): ¿Cuál es su experiencia con Odoo (software ERP y de gestión empresarial) en configuración funcional, desarrollo de módulos, integraciones, seguridad y administración?
Esta página cubre 10 bloques del temario: fundamentos y versiones (Q1–Q8), arquitectura técnica y despliegue (Q9–Q16), modelo de datos y ORM (Q17–Q25), desarrollo de módulos y vistas (Q26–Q34), módulos funcionales de ventas, compras, inventario y manufactura (Q35–Q43), contabilidad y finanzas (Q44–Q51), integraciones (Q52–Q59), seguridad y usuarios (Q60–Q67), multi-compañía, datos maestros, migración y calidad (Q68–Q74) y administración, rendimiento y operaciones (Q75–Q82), más una plantilla de respuesta para entrevista y referencias.
Q1. ¿Qué es Odoo y para qué tipo de soluciones se usa?
Odoo es una suite integrada de aplicaciones de gestión empresarial (ERP + CRM + comercio electrónico + punto de venta + recursos humanos) de código abierto, desarrollada por la empresa belga Odoo S.A. Su propuesta de valor es que todas las aplicaciones comparten un único modelo de datos y un único motor de permisos: ventas, inventario, compras, manufactura, contabilidad, proyectos y sitio web se conectan sin integraciones a medida. Se usa en pymes y mid-market para reemplazar combinaciones de hojas de cálculo y software puntual, y también en empresas grandes como capa de procesos específicos (por ejemplo, eCommerce o helpdesk) integrada con un ERP corporativo. Es especialmente popular en Europa, Latinoamérica, India y África del Norte.
Q2. ¿Cuál es la historia y evolución de Odoo (TinyERP, OpenERP, Odoo)?
El proyecto nació en 2005 como TinyERP, creado por Fabien Pinckaers; en 2008 se renombró OpenERP y en 2014, con la versión 8, pasó a llamarse Odoo para reflejar que ya no era solo un ERP sino una plataforma de aplicaciones de negocio (incluyendo sitio web, eCommerce y POS). Hitos técnicos relevantes: la introducción del nuevo API de módulos y de la web moderna en v8/v9, la aparición de Odoo.sh, el framework de frontend OWL a partir de v14/v15 (reemplazando el antiguo sistema de widgets), y la incorporación de Spreadsheet, Knowledge y mejoras profundas de contabilidad y de la interfaz en las versiones más recientes. Odoo publica una versión mayor cada año, normalmente presentada en el evento Odoo Experience (octubre).
Q3. ¿Qué diferencia a Odoo Community de Odoo Enterprise?
Q4. ¿Qué opciones de despliegue y hospedaje existen?
Q5. ¿Cómo funciona el licenciamiento y el modelo de precios?
Community es gratuita y está bajo LGPL-3, lo que permite usarla, modificarla y redistribuirla respetando la licencia; los módulos Enterprise usan una licencia de uso por suscripción (Odoo Enterprise Edition License) asociada al número de usuarios. El modelo comercial actual de Odoo se organiza por usuario y plan: un plan gratuito para una sola app u Online, un plan Standard y un plan Custom (que añade Odoo.sh, el servicio de upgrades y más soporte). Los módulos de terceros de la Odoo Apps Store tienen licencias propias (muchos bajo LGPL u OPL). En un proyecto real hay que presupuestar: licencias por usuario, hosting, partner de implementación, módulos de terceros y el costo de mantenimiento y upgrades entre versiones.
Q6. ¿Cómo se versiona Odoo y qué implica el ciclo anual de releases?
Odoo publica una versión mayor al año (v16, v17, v18, v19 y siguientes), cada una con soporte oficial durante tres versiones mayores. Cada release trae cambios en el framework (ORM, vistas, OWL), en los módulos funcionales (especialmente contabilidad e inventario) y en el esquema de base de datos, por lo que migrar no es automático: hay que ejecutar scripts de migración y adaptar los desarrollos propios. En la práctica los equipos deciden entre: mantenerse en una versión estable y migrar cada 2–3 releases, o seguir el ritmo anual. Antes de migrar se evalúan los módulos custom, los módulos de terceros (que deben existir para la versión destino) y el esfuerzo de pruebas de regresión.
Q7. ¿Cómo se compara Odoo con otros ERP (SAP, Oracle NetSuite, Microsoft Dynamics)?
Q8. ¿Qué es la OCA y cómo es el ecosistema de módulos de terceros?
La OCA (Odoo Community Association) es una organización sin ánimo de lucro que mantiene miles de módulos gratuitos y de código abierto, con estándares de calidad, revisión por pares, guías de mantenibilidad y procesos de migración colaborativa (OpenUpgrade). Sus repositorios están organizados por dominio: account-financial-tools, stock-logistics-warehouse, sale-workflow, server-tools, web, l10n-spain / l10n-colombia / l10n-mexico (localizaciones), entre otros. Junto a la OCA existe la Odoo Apps Store con módulos comerciales de pago. En un proyecto conviene priorizar módulos OCA antes que desarrollar desde cero, verificando siempre: mantenimiento activo para la versión usada, licencia, calidad del código y que no dupliquen funcionalidad estándar.
Q9. ¿Cuál es el stack tecnológico de Odoo?
Q10. ¿Cómo está estructurada la arquitectura interna?
En capas, de arriba hacia abajo: (1) el cliente web (navegador con OWL, la app móvil o el POS) consume el (2) servidor HTTP de Odoo, que enruta peticiones JSON-RPC hacia controladores o hacia el ORM; (3) el ORM traduce operaciones de alto nivel (create, write, search, unlink) a SQL, aplicando permisos, reglas de registro, campos computed y constraints; (4) PostgreSQL persiste los datos. Toda la configuración de negocio (vistas, acciones, menús, reglas de acceso, trabajos programados) es también dato en la base, no solo código: por eso un cambio de UI puede hacerse desde la interfaz sin desplegar. Los adjuntos y assets generados viven en el filestore, fuera de la base de datos.
Q11. ¿Qué es un «addon» y cómo se resuelve el addons_path?
Un addon (o módulo) es una carpeta autocontenida con un manifiesto (__manifest__.py), código Python (__init__.py, models/, wizards/, controllers/), datos (data/, security/, views/, report/) y recursos estáticos (static/). Odoo busca módulos en la lista de rutas configurada en addons_path (parámetro de odoo.conf o de línea de comandos), en orden: la primera coincidencia gana, de modo que un addon propio puede «sombrear» a uno estándar si comparte nombre (práctica desaconsejada; es mejor heredar). Buenas prácticas: separar addons estándar, OCA y desarrollos propios en rutas distintas, versionar los custom en Git y no modificar nunca el código core.
Q12. ¿Qué son el registry, el environment (env) y el cursor?
cr): la conexión/cursores de base de datos; delimita la transacción. Odoo hace commit al finalizar la petición y rollback ante cualquier excepción.env): objeto que combina cursor + usuario + contexto (env.cr, env.user, env.company, env.context, env.company_ids). Todo acceso al ORM pasa por él; env['sale.order'] devuelve un recordset vacío del modelo, sobre el que se opera.Q13. ¿Cómo funciona el modelo de workers y el longpolling?
En producción Odoo corre en modo multiproceso (prefork): un proceso maestro lanza workers HTTP que atienden peticiones y workers cron que ejecutan acciones programadas. Se configuran con workers, max_cron_threads, limit_memory_soft/hard, limit_time_cpu, limit_time_real y limit_request. Además hay un worker gevent/longpolling para notificaciones en tiempo real (bus, live chat, POS en tiempo real), normalmente expuesto en el puerto 8072 y proxificado bajo la ruta /longpolling o /websocket. Regla práctica de dimensionamiento: varios workers por núcleo de CPU según memoria disponible, límites de tiempo acordes a los procesos más largos (importaciones, informes) y workers cron separados para que un trabajo pesado no degrade la respuesta de la UI.
Q14. ¿Cómo se configura nginx / reverse proxy y TLS en producción?
Se activa el modo proxy en Odoo (proxy_mode = True) para que lea las cabeceras X-Forwarded-For/X-Forwarded-Proto, y se configuran en nginx: TLS (certificados, idealmente renovación automática con Let's Encrypt), redirección HTTP→HTTPS, proxy_pass al puerto 8069 y al puerto de longpolling (8072) según la ruta, cabeceras de forwarded, timeouts generosos (proxy_read_timeout) para informes e importaciones, límite de tamaño de cuerpo (client_max_body_size) acorde a adjuntos, cache/compresión de assets estáticos (/web/static, /longpolling sin caché) y bloqueo de rutas sensibles (/web/database en producción, list_db = False). También conviene cabeceras de seguridad (HSTS, X-Content-Type-Options, X-Frame-Options/CSP) y logging separado para auditoría.
Q15. ¿Qué es OWL y cómo se organiza el frontend?
OWL (Odoo Web Library) es el framework de componentes en el que está construido el cliente web moderno de Odoo: componentes con estado reactivo, plantillas QWeb compiladas en el navegador, hooks (useState, onWillStart, onMounted) y un sistema de servicios inyectados por el entorno. Sustituye al antiguo sistema de widgets. Para personalizar UI se usan: patches sobre componentes o servicios existentes (método estándar para extender sin duplicar), registros en el registry del cliente web (por ejemplo, campos personalizados con componente propio, vistas personalizadas), templates QWeb heredados con t-extend/xpath y bundles de assets declarados en el manifiesto (assets). En integraciones headless se puede consumir el ORM directamente por JSON-RPC/XML-RPC y construir el frontend fuera de Odoo.
Q16. ¿Cómo se administra multi-base de datos en una misma instancia?
Un proceso Odoo puede servir varias bases de datos: se selecciona por URL (/web?db=nombre), por el selector de bases o por filtro. En producción se recomienda list_db = False y dbfilter con expresión regular (por ejemplo ^%h$ para una base por hostname, o db_name para fijar una sola), de modo que no se exponga el listado ni se pueda entrar a otra base. Cada base tiene su propio registry, su filestore (carpeta por base dentro del directorio de datos) y su conjunto de módulos instalados. Es útil para entornos dev/test/productivo en un mismo servidor o para clientes multi-tenant de un partner, pero exige cuidar backups por separado, consumo de memoria (un registry por base cargada) y aislamiento de rendimiento.
Q17. ¿Cómo se define un modelo en Odoo?
Con una clase Python que hereda de models.Model y declara _name (nombre técnico, que genera la tabla SQL con guiones bajos), _description, los campos como atributos de clase y opcionalmente _order, _rec_name, _rec_names_search, _sql_constraints y _inherit. Por ejemplo: class Visita(models.Model): _name = 'crm.visita'; _description = 'Visita comercial'; fecha = fields.Date(required=True); partner_id = fields.Many2one('res.partner', required=True, index=True). Sobre esa declaración Odoo crea la tabla, los índices, las constraints y expone automáticamente el modelo a vistas, permisos, exportación e importación, sin necesidad de escribir SQL ni endpoints.
Q18. ¿Qué tipos de modelos existen y cuándo se usa cada uno?
Q19. ¿Qué tipos de campos hay y qué atributos son importantes?
Tipos básicos: Char, Text, Html, Integer, Float, Monetary, Boolean, Date, Datetime, Selection, Binary, Image; relacionales: Many2one, One2many, Many2many, Reference. Atributos clave: string (etiqueta), required, readonly, default (valor o función), help, index, copy, translate, groups (restringe el campo a ciertos grupos), tracking (registra cambios en el chatter), company_dependent, digits/rounding en numéricos, selection con opción dinámica y attachment en binarios. En Many2one: domain, ondelete (set null / restrict / cascade), delegate, check_company. En x2many: comodel_name, inverse_name, domain, context (por ejemplo default_*) y auto_join para optimizar búsquedas. Definir bien los atributos evita validaciones duplicadas en la UI y en el código.
Q20. ¿Cómo funcionan los campos computed, almacenados e inverse?
Un campo con compute='_compute_x' se calcula con un método decorado con @api.depends('campo1','campo2'), que recibe un recordset y asigna el valor a cada registro; debe asignar siempre un valor a todos los registros para evitar errores en registros nuevos. Con store=True el resultado se persiste y se recalcula cuando cambian las dependencias, lo que permite buscar y ordenar por él (útil para totales o estados derivados), a cambio de costo de escritura y de migraciones cuando cambian las dependencias. Con inverse='_inverse_x' se define qué hacer cuando el usuario escribe en el campo calculado. También existe search= para hacer buscables campos no almacenados y precompute=True para calcular antes del insert. Regla práctica: almacenar solo lo que se filtra/agrega en listados o informes.
Q21. ¿Qué son los campos related y company_dependent?
related: expone un campo de un modelo enlazado a través de una cadena de relaciones, por ejemplo partner_email = fields.Char(related='partner_id.email'); puede ser de solo lectura o editable (con inverse implícito), y si se almacena (store=True) con sus depends correspondientes permite filtrar sin joins costosos. Sirve para evitar lógica duplicada y para dar visibilidad en formularios. company_dependent: el valor se guarda por compañía (en una tabla de propiedades/JSON según la versión), de modo que el mismo producto o contacto puede tener cuenta contable, precio o responsable distinto en cada empresa del grupo; es esencial en configuraciones multi-compañía y requiere que el contexto lleve la compañía correcta.
Q22. ¿Cómo funcionan las relaciones x2many y sus comandos?
En One2many y Many2many las escrituras se expresan como lista de comandos triples: (0, 0, valores) crear nuevo registro; (1, id, valores) actualizar uno existente; (2, id, 0) eliminar y desvincular (unlink); (3, id, 0) desvincular sin eliminar; (4, id, 0) vincular existente; (5, 0, 0) desvincular todos; (6, 0, [ids]) reemplazar el conjunto completo por esa lista. En versiones recientes existen constantes legibles (Command.create, Command.update, Command.delete, Command.unlink, Command.link, Command.clear, Command.set). Conocerlos evita bugs clásicos al editar líneas de pedidos o etiquetas desde código, sobre todo la diferencia entre unlink (2) y clear (5) y el efecto destructivo de set (6).
Q23. ¿Cómo se hace herencia de modelos en Odoo?
_inherit = 'sale.order' sin _name añade campos y sobrescribe métodos al modelo existente en la misma tabla. Es la forma estándar de customizar el core._inherit = 'mail.thread' junto a _name propio copia campos y métodos del modelo padre al nuevo (mixins)._inherits = {'res.partner': 'partner_id'} compone una tabla nueva que referencia a otra; el registro hijo expone los campos del padre como propios (por ejemplo res.users delega en res.partner).super() respetando el MRO para no romper la cadena de extensiones de otros módulos; el orden de carga lo determinan las dependencias del manifiesto.
Q24. ¿Qué métodos y decoradores del ORM hay que dominar?
CRUD y consultas: create (decorado con @api.model_create_multi para lotes), write, unlink, search, search_count, browse, read, read_group (agregados, base de muchos informes), name_search, default_get, copy. De recordset: filtered, mapped, sorted, exists, ensure_one. Decoradores: @api.model (métodos sin registro, p. ej. utilidades), @api.depends (campos computed), @api.depends_context (dependencias de contexto), @api.onchange (reacción en el formulario, no persiste lógica de negocio), @api.constrains (validaciones Python que lanzan ValidationError), @api.autovacuum (limpieza periódica). Además: overrides de create/write/unlink para efectos laterales, y gestión de dominios (&, |, ! y listas de tuplas) que es el lenguaje de filtrado del ORM. Diferencia crítica: onchange solo afecta a la UI; la validación real va en constrains o en el override de create/write.
Q25. ¿Cómo se cargan datos iniciales y qué son los XML IDs?
Los módulos declaran datos en archivos XML (o CSV) listados en data del manifiesto. Cada registro lleva un id externo (xml_id), único por módulo, que se guarda en ir.model.data y permite referenciarlo desde otros archivos con ref() o desde código con env.ref('modulo.xml_id'). Con noupdate="1" el registro no se sobrescribe en actualizaciones posteriores (típico en secuencias, plantillas de correo o configuración que el usuario puede editar). Para permisos se usa ir.model.access.csv (grupos y CRUD por modelo) y para reglas de registro ir.rule en XML. Al instalar se cargan todos los datos; al actualizar (-u) se recargan respetando noupdate. Los datos demo (demo del manifiesto) solo se cargan si la base se crea con datos de demostración.
Q26. ¿Cuál es la estructura recomendada de un módulo Odoo?
Q27. ¿Qué contiene el __manifest__.py?
Es un diccionario Python con: name, summary, description, author, website, category, version (se recomienda seguir la convención versión_de_odoo.módulo.parche, por ejemplo 17.0.1.2.0), license (LGPL-3, AGPL-3, OEEL-1, OPL-1), depends (módulos requeridos: determina el orden de carga y la disponibilidad de modelos), data (archivos XML/CSV a cargar siempre), demo, assets (bundles de JS/CSS/XML del cliente web), application, auto_install, installable, external_dependencies (librerías Python o binarios), post_init_hook/uninstall_hook y sequence. Un depends preciso evita errores de carga y acoplamientos innecesarios: solo se declara lo que el código usa realmente.
Q28. ¿Cómo se instala, actualiza y desinstala un módulo?
Desde la interfaz (Apps, tras activar el modo desarrollador y «Actualizar lista de módulos») o por línea de comandos con odoo-bin -d basededatos -i nombre_modulo (instalar) y -u nombre_modulo (actualizar; -u base o -u all para todo). En desarrollo se usa --dev=all o --dev=reload,qweb,xml para recargar código y plantillas sin reiniciar, y en pruebas --test-enable con --stop-after-init. La actualización re-carga los datos XML/CSV no marcados noupdate, recrea vistas y actualiza la estructura de tablas si hay campos nuevos; no ejecuta migraciones de datos complejas (para eso existen los scripts en migrations/ con la versión del manifiesto). La desinstalación borra datos del módulo y puede arrastrar dependencias inversas, por lo que en producción siempre se prueba antes en staging.
Q29. ¿Qué tipos de vistas hay y cómo se configuran?
Vistas principales: form (formulario con sheet, group, notebook/page, chatter, botones, statusbar), list/tree (columnas, decoraciones, editable="top|bottom", agregados en el pie), kanban (tablero por etapas con plantillas QWeb), search (campos, filter y group para agrupar), calendar, gantt (Enterprise), pivot y graph (análisis), activity, cohort (Enterprise), graph/dashboard y vistas del portal/web con QWeb. Atributos frecuentes: domain (filtrado), context (valores por defecto default_*, agrupaciones), attrs/invisible/readonly/required (en versiones modernas se usan directamente expresiones Python en esos atributos), groups (visibilidad por grupo) y widget (por ejemplo many2many_tags, monetary, selection_badge, percentpie). Cada vista tiene prioridad e id externo; la UI puede modificarlas (modo desarrollador → editar vista).
Q30. ¿Cómo funciona la herencia de vistas con xpath?
Se declara una vista con inherit_id apuntando a la vista base y un cuerpo de xpath con posiciones: inside (añadir al final del nodo), after/before (hermano siguiente/anterior), replace (sustituir el nodo, puede usar t-call o mantener parte del contenido) y attributes (modificar atributos, con attribute name="invisible", separator, o add/remove para listas como groups). También existe la herencia por posición con position="move" y las vistas QWeb heredadas con t-extend/t-call en el frontend. Buenas prácticas: usar selectores estables (//field[@name='x'] o //div[hasclass('oe_title')]) en lugar de índices frágiles, mantener la prioridad correcta y no reemplazar bloques completos cuando basta con añadir.
Q31. ¿Qué son las acciones y cómo se estructuran los menús?
Las acciones (ir.actions.*) describen qué debe hacer el cliente: act_window (abre un modelo con vistas, dominio, contexto y modo), server (ejecuta código Python, crea/actualiza registros, lanza otra acción o envía notificaciones), client (acciones predefinidas del cliente como display_notification), report (genera PDF/documento) y url (redirige). Los menús (ir.ui.menu) son registros con padre, secuencia, acción asociada y groups que controlan la visibilidad. Toda la navegación es dato en base, por eso se puede reorganizar desde la interfaz. Al extender un ERP existente, definir acciones y menús coherentes con la app anfitriona mejora la adopción por parte de los usuarios.
Q32. ¿Qué diferencia hay entre server actions, automated actions y scheduled actions?
Q33. ¿Cómo se crea un wizard y cómo se devuelve el resultado?
Se define un TransientModel con los campos de entrada, una vista form y una acción act_window con target='new' para abrirlo como diálogo; se invoca desde un botón (type="action") o desde una acción de servidor. El método de confirmación (botón type="object") procesa los datos usando self.env.context.get('active_ids')/active_id/active_model y devuelve: None (cierra el diálogo), True/False, un diccionario de acción (para navegar a los registros creados, por ejemplo ir.actions.act_window con res_id), o una notificación mediante display_notification. Los campos relacionados con el modelo origen se suelen poblar con default_get y el wizard puede tener varias pantallas usando un campo de estado y invisible en la vista.
Q34. ¿Cómo se generan reportes PDF y documentos personalizados?
Con QWeb: se declara un informe (ir.actions.report) y una plantilla <template id="report_x"> que hereda de web.external_layout (o un layout propio) e itera sobre los registros con t-foreach="docs", usando t-field (respeta formato de fecha/moneda), t-esc/t-out, t-if y llamadas a métodos del modelo (t-call a sub-plantillas). Odoo renderiza el HTML y lo convierte a PDF con wkhtmltopdf, por lo que hay que cuidar CSS de paginación (page-break-inside, @page), cabeceras/pies por página y el tamaño de los datasets. Existen además informes financieros dinámicos (Enterprise) exportables a Spreadsheet/PDF, informes XLSX (módulos OCA como report_xlsx) y diseñadores visuales (Studio, o editores de plantillas de documentos). Para documentos transaccionales también se usan plantillas de correo QWeb.
Q35. ¿Qué apps funcionales trae Odoo y cómo se integran entre sí?
Q36. ¿Cómo es el flujo order-to-cash en Odoo?
Presupuesto (sale.order en estado draft) → envío por correo con portal del cliente y firma electrónica/pago en línea → confirmación a pedido (state='sale'), momento en el que se generan las entregas (stock.picking) según la ruta del producto y, si aplica, pedidos de compra u órdenes de fabricación → picking con confirmación de cantidades (lotes/series) → facturación según la política del producto (cantidades pedidas o entregadas, manual o automática, por hitos o por consumo en proyectos) → account.move validado que genera el asiento contable → registro de pago (manual, pasarela, adeudo SEPA/NACHA) → conciliación con el extracto bancario → seguimiento de cobranza (niveles de recordatorio). Cada paso deja trazabilidad en el chatter y en los documentos vinculados del pedido.
Q37. ¿Cómo es el flujo procure-to-pay y qué es el 3-way matching?
Necesidad de abastecimiento (regla de reorden, MTO desde una venta, o solicitud manual) → solicitud de presupuesto (RFQ) purchase.order → opción de acuerdos de compra/licitaciones para comparar proveedores → confirmación del pedido (genera recepción stock.picking entrante) → recepción con validación de cantidades, lotes y posibles devoluciones → factura de proveedor creada desde el pedido o importada por OCR/correo → 3-way matching: Odoo compara pedido, recepción y factura para permitir facturar solo lo recibido y detectar diferencias de precio o cantidad → pago y conciliación bancaria → impacto en el costeo de inventario y en la contabilidad. Los controles de aprobación (por importe, por grupo de usuario) y las variantes de proveedor (precio, plazo, cantidad mínima) se configuran en la ficha del producto.
Q38. ¿Cómo funciona el inventario: ubicaciones, quants y la «doble entrada»?
Odoo modela el stock como un sistema de doble entrada: no hay «borrado» de existencias sino movimientos entre ubicaciones, igual que los asientos contables. Una ubicación (stock.location) puede ser física (almacén/zona/estante), virtual (proveedores, clientes, producción, pérdidas, inventario) o de tránsito. El movimiento (stock.move) representa la transferencia de un producto entre dos ubicaciones; stock.move.line es la ejecución concreta con cantidades, lotes y empaques; stock.quant guarda la cantidad disponible por producto/ubicación/lote. Los pickings agrupan movimientos en un documento operativo (recepción, entrega, transferencia interna). Esto da trazabilidad completa, permite reservas parciales, gestiona cantidades reservadas/disponibles/a la mano y hace que el inventario cuadre con la contabilidad cuando la valoración es automática.
Q39. ¿Qué son las rutas y las reglas push/pull?
Una ruta (stock.route) es un conjunto de reglas que define el camino de un producto desde el origen hasta el destino; se asigna a producto, categoría de producto, almacén o línea de pedido. Las reglas pull generan un movimiento cuando hay demanda (por ejemplo, entregar desde stock, o fabricar/comprar si no hay: MTO), y las reglas push mueven el producto después de recepcionarlo (por ejemplo, de recepción a zona de control de calidad y luego a existencias). Combinaciones típicas: MTS (make to stock, desde existencias), MTO (make to order, dispara compra o fabricación), Buy, Manufacture, Dropship (el proveedor entrega directo al cliente), Cross-dock, rutas de dos o tres pasos con picking/packing, subcontratación y rutas multi-almacén. Configurar mal las rutas es la causa más frecuente de incidencias operativas, por lo que conviene documentarlas y probarlas con casos reales.
Q40. ¿Cómo se gestionan lotes, números de serie, caducidad y trazabilidad?
Se activa en la ficha del producto la trazabilidad por lotes (un identificador para varias unidades, común en alimentos o farmacia) o por números de serie (uno por unidad, para garantías y activos). En los movimientos se capturan lotes/series con fechas de fabricación y caducidad, y Odoo permite reglas de retirada (removal strategies) como FEFO, FIFO o LIFO por ubicación. Con eso se obtiene trazabilidad ascendente y descendente: desde un lote se ven clientes y proveedores afectados, y desde una entrega se rastrea el lote. A esto se suman empaques (packages), unidades de medida (con categorías y factores de conversión), y en Enterprise la app de código de barras para operación con lectores. Los procesos de retirada (recalls) y de control de calidad se apoyan en esta trazabilidad.
Q41. ¿Cómo funcionan el reabastecimiento y la planificación de la demanda?
Con reglas de reorden (stock.warehouse.orderpoint): cantidad mínima y máxima por producto y ubicación; cuando el stock previsto cae bajo el mínimo, el planificador genera la necesidad y, según la ruta, un RFQ de compra o una orden de fabricación. Odoo incluye una vista de Previsión/Reabastecimiento que muestra necesidades por fecha, permite ajustar cantidades, agrupar en un solo pedido por proveedor y considerar plazos de compra/fabricación, cantidades míntimas y múltiplos de empaque. En Enterprise existen el planificador MPS (Master Production Schedule) y el forecast con predicciones de venta. Buenas prácticas: revisar la frecuencia del cron de planificación, mantener limpios los plazos y mínimos, y controlar las órdenes canceladas para no duplicar compras.
Q42. ¿Cómo funciona MRP: listas de materiales, centros de trabajo y órdenes?
La lista de materiales (BoM) define componentes, cantidades y tipo: manufacture (produce un producto), kit (conjunto que se descompone en líneas de venta/compra sin paso por producción) o subcontracting. Puede tener variantes de producto, componentes alternativos y operaciones. Los centros de trabajo (work centers) modelan máquinas o líneas con capacidad, eficiencia, costo por hora y calendario (OEE y tiempos alternativos en Enterprise), y las operaciones (rutas de fabricación) asignan tiempo y centros a cada paso. La orden de fabricación (MO) reserva componentes, genera movimientos de consumo y de producto terminado, y registra órdenes de trabajo con tablet/kanban, tiempos reales, desperdicio (scrap) y subproductos. Con PLM, mantenimiento y calidad (Enterprise) se añaden versiones de BoM, órdenes de cambio de ingeniería, avisos de mantenimiento y puntos/control de calidad.
Q43. ¿Qué métodos de costeo y valoración de inventario existen?
En la categoría de producto se define el método de costeo: Standard (precio fijo manual), FIFO (primeras entradas, primeras salidas) o AVCO (coste medio ponderado); y la valoración: manual (sin asientos automáticos) o automática/anglo-sajona (cada movimiento genera asientos contables en tiempo real contra cuentas de existencias y de variación, usando stock.valuation.layer). Sobre el coste se pueden aplicar landed costs (fletes, seguros, aranceles) que se reparten por peso, volumen, cantidad o valor y actualizan el coste de los productos recibidos. La contabilidad anglo-sajona separa el ingreso del coste en el momento de la entrega, necesario para márgenes correctos. Cambiar de método en producción requiere depuración y migración de capas de valoración, por lo que debe decidirse al inicio del proyecto.
Q44. ¿Qué incluye la contabilidad en Odoo y en qué se diferencia Community de Enterprise?
El núcleo (account) gestiona el plan contable, diarios, impuestos, asientos (account.move), facturas de cliente y proveedor, pagos, conciliación básica, multi-moneda y contabilidad analítica. En Community la app se presenta como Invoicing: emite facturas y registra pagos, pero no trae los informes financieros dinámicos completos ni muchas herramientas avanzadas (muchas se cubren con módulos OCA del repositorio account-financial-tools). Enterprise añade contabilidad completa: balances y PyG dinámicos, flujo de caja, libro mayor interactivo, informes de impuestos, activos, ingresos y gastos diferidos, presupuestos, cheques y órdenes de pago, sincronización bancaria, OCR de facturas de proveedor, seguimiento de cobranza con niveles y recordatorios, y localizaciones contables mantenidas por Odoo. En implementaciones financieras regulatorias es la diferencia decisiva.
Q45. ¿Cómo se configura el plan contable, los diarios y los impuestos?
Se instala la localización contable del país (por ejemplo l10n_co, l10n_mx, l10n_es, l10n_us), que trae el plan de cuentas (paquete fiscal), los impuestos predefinidos, los informes legales y, donde aplica, la facturación electrónica. Sobre eso se ajustan: cuentas por tipo (por pagar, por cobrar, existencias, variaciones, ingresos y gastos por categoría de producto), diarios (ventas, compras, banco, caja, misceláneos, con numeración y cuentas por defecto), secuencias de numeración, posiciones fiscales (mapean impuestos y cuentas según el país del cliente, esencial en comercio internacional) y grupos de impuestos (retenciones). Además se configuran condiciones de pago, cuentas por defecto en categorías de producto/partner y el cierre fiscal (bloqueo de fechas y periodos).
Q46. ¿Qué es account.move y cómo se relaciona con facturas y asientos?
Desde Odoo 13 las facturas y los asientos comparten el mismo modelo account.move, diferenciado por move_type: out_invoice (factura de cliente), out_refund (nota crédito), in_invoice (factura de proveedor), in_refund, out_receipt, in_receipt y entry (asiento contable manual). Sus líneas son account.move.line, que llevan cuenta, importe, impuestos, analítica y vencimiento. Al validar (action_post) el documento se convierte en asiento con estado posted y ya no es editable; las correcciones se hacen con notas crédito/débito o con la funcionalidad de reversión. Los pagos (account.payment) se concilian contra las líneas de vencimiento. Entender este modelo es clave para desarrollos: casi toda la customización financiera toca account.move y sus constraints.
Q47. ¿Cómo funcionan la conciliación bancaria y la sincronización de bancos?
Existen dos vías: importación de extractos (archivos CAMT.053, OFX, QIF, CSV) o sincronización automática con agregadores bancarios soportados (según país y plan). Con el extracto en Odoo se concilia: cada línea bancaria se empareja con asientos existentes (facturas, pagos) o se crea un asiento nuevo, usando reglas de conciliación automáticas por concepto, importe, referencia o partner, y sugerencias basadas en histórico. Las diferencias se llevan a cuentas de descuadre o a ganancias/pérdidas por cambio. También existe la conciliación de cuentas transitarias y de pagos múltiples. Automatizar reglas reduce drásticamente el trabajo mensual; conviene revisar periódicamente que las reglas no oculten errores (por ejemplo, comisiones bancarias mal imputadas).
Q48. ¿Cómo se maneja multi-moneda y diferencias de cambio?
Se activan las monedas necesarias y se actualizan sus tasas (manual o automáticamente desde el BCE u otras fuentes). Cada documento guarda currency_id y la tasa aplicada; los importes en moneda de la compañía se calculan con esa tasa. Las diferencias surgen entre el momento de la factura, el del pago y el del cierre, y Odoo genera asientos de diferencia de cambio (realizadas al conciliar, y no realizadas en la revalorización de saldos al cierre, funcionalidad según versión/edición). Puntos de atención: cuentas con currency_id forzada, tasas históricas correctas, redondeos por moneda (decimal_places) y políticas de cobertura. En grupos multi-compañía con monedas distintas también interviene la conversión para informes consolidados.
Q49. ¿Qué es la contabilidad analítica y cómo se configura?
La contabilidad analítica reparte ingresos y gastos por dimensiones de gestión sin afectar la contabilidad legal. Desde v16 se organiza con planes analíticos (account.analytic.plan) que pueden combinarse (por proyecto, por centro de coste, por línea de negocio, por canal) y cuentas analíticas (account.analytic.account) dentro de cada plan. Las líneas analíticas (account.analytic.line) registran los importes por dimensión; partes de horas, gastos y facturas pueden distribuirlas automáticamente, y las reglas de distribución permiten imputar porcentajes. Con esto se obtienen PyG por proyecto, margen por cliente o coste por centro, y es la base de la facturación por proyectos y del control presupuestario.
Q50. ¿Cómo funcionan activos, diferidos y presupuestos?
Activos (account.asset, Enterprise/OCA en Community): se crean desde la factura de proveedor o manualmente, con método de depreciación (lineal, degresivo, degresivo-lineal), vida útil o número de depreciaciones, cuenta de activo, de depreciación y de gasto; Odoo genera el plan de depreciación y los asientos periódicos, y gestiona bajas y ventas del activo. Diferidos: ingresos o gastos reconocidos en varios periodos (por ejemplo una suscripción anual) con plantillas de diferido que generan los asientos de reconocimiento mes a mes. Presupuestos: se define un presupuesto por cuenta analítica y periodo, y los informes comparan lo presupuestado con lo comprometido (pedidos) y lo real (asientos), permitiendo alertas. Los tres bloques dependen de una buena configuración analítica y de fechas de bloqueo correctas.
Q51. ¿Qué informes financieros y fiscales existen y cómo se personalizan?
Informes estándar (Enterprise o módulos OCA): balance de situación, pérdidas y ganancias, balance de sumas y saldos, libro mayor y diario, balances de terceros (aged partner balance de cobros y pagos), estado de flujo de caja, informes de impuestos (IVA/IGIC/retenciones según localización), informes intrastat, análisis de facturación y los tableros con Spreadsheet. Se personalizan con: filtros de fecha/periodo/comparativa (varios periodos en columnas), jerarquías de cuentas definidas por el usuario, agrupaciones por dimensión analítica, y exportación a PDF/XLSX/CSV. Además, los informes de Odoo están definidos como modelos con fórmulas por línea, de modo que se pueden crear informes propios con código o, en Enterprise, editarlos con la interfaz. Para requisitos regulatorios locales siempre hay que validar con el contador y la localización oficial.
Q52. ¿Qué mecanismos ofrece Odoo para integrarse con sistemas externos?
Q53. ¿Cómo funciona la API externa (execute_kw)?
El flujo es: (1) autenticar con common.authenticate(db, login, api_key/password, {}), que devuelve el uid; (2) invocar object.execute_kw(db, uid, key, model, method, args, kwargs). Ejemplos de métodos: search (con dominio y kwargs como fields, limit, offset, order), search_read, read, create (lista de dicts), write (ids + dict), unlink, name_search, read_group y cualquier método público de los modelos. Desde Python se usa xmlrpc.client.ServerProxy; desde otros lenguajes, peticiones JSON-RPC con jsonrpc: '2.0', method: 'call' y los parámetros en params. Buenas prácticas: operaciones por lotes (nunca un write por registro), fields explícitos para no traer todo, manejo de AccessError/ValidationError, y versionado del código de integración.
Q54. ¿Qué son las API keys y cómo se autentica un sistema externo?
Desde versiones recientes la autenticación por API se hace con claves de API generadas por el usuario en sus preferencias (en lugar de la contraseña), lo que permite revocarlas individualmente, auditarlas y no exponer credenciales en scripts. Además Odoo soporta OAuth2 como cliente (auth_oauth, para iniciar sesión con Google/Microsoft u otro IdP) y, en versiones nuevas, como proveedor para aplicaciones externas, junto con SSO/SAML mediante módulos. En integraciones hay que: crear usuarios técnicos dedicados con permisos mínimos (grupos específicos por modelo, no administración), almacenar las claves en un gestor de secretos, rotarlas periódicamente, limitar por IP donde sea posible y registrar los accesos. Nunca se debe incrustar la contraseña de un usuario real en un sistema externo.
Q55. ¿Cómo se desarrollan controladores HTTP y endpoints propios?
En controllers/ se declaran clases con @http.route('/ruta', type='json'|'http', auth='public'|'user'|'none', methods=['POST','GET'], csrf=True|False, cors='*'). type='json' usa JSON-RPC y devuelve datos serializables; type='http' devuelve respuestas HTTP normales (JSON manual, archivos, redirecciones, páginas QWeb con request.render). auth determina quién puede llamar: public (usuario público), user (sesión requerida) o none (sin usuario; se debe abrir cursor explícitamente con odoo.api.Environment). Para webhooks entrantes se valida la firma o el token en cabecera, se responde rápido y se delega el proceso pesado a un cron o a una cola de trabajos. Seguridad: CSRF activo en rutas con sesión de navegador, validación estricta de entradas, rate limiting en el proxy y logs de cada llamada.
Q56. ¿Cómo se integran pagos, envíos y servicios IAP?
Pagos: Odoo tiene proveedores de pago configurables (por ejemplo Stripe, PayPal, Adyen, Authorize.Net, Buckaroo, Mollie, Razorpay, Sips, Mercado Pago y otros según versión y localización) que se usan en eCommerce, POS, portal de facturas y pagos recurrentes en suscripciones; manejan tokens, webhooks de confirmación y conciliación automática del pago con la factura. Envíos/transportistas: conectores con UPS, FedEx, DHL, USPS, Bpost, Sendcloud y otros para obtener tarifas, generar etiquetas y numeración de seguimiento desde el picking. IAP (In-App Purchase): servicios de Odoo por créditos: OCR y digitalización de facturas de proveedor, validación de números de IVA, envío de SMS, correo postal (Snailmail), búsqueda de leads y llamadas telefónicas VoIP. En todos los casos hay que diseñar el manejo de fallos: reintentos, estados intermedios y alertas cuando el proveedor no responde.
Q57. ¿Cómo se maneja EDI y facturación electrónica?
Odoo soporta formatos y esquemas estándar a través del marco EDI (account_edi en Enterprise): UBL 2.1, CII, Factur-X/ZUGFeRD (PDF híbrido), PEPPOL para intercambio entre empresas en Europa, y exportaciones bancarias SEPA/ISO 20022 y NACHA. Además, las localizaciones implementan requisitos fiscales nacionales (por ejemplo CFDI en México, SII/Verifactu en España, facturación electrónica en Colombia, Chile, Perú, India GST/e-invoicing, EET, etc.), algunas mantenidas por Odoo y otras por partners u OCA. En la práctica el diseño incluye: numeración y prefijos correctos, representación PDF/A exigida, firma y sello con el proveedor autorizado (PAC/DIAN/SAT según país), reintentos ante rechazo, almacenamiento de los XML de respuesta y trazabilidad del estado del documento. Cuando un país no tiene localización oficial, se integra con un proveedor externo vía API.
Q58. ¿Cómo se diseñan integraciones robustas (colas, reintentos, idempotencia)?
Principios: idempotencia (clave única de negocio o constraint SQL para no duplicar pedidos/facturas al reintentar), procesamiento asíncrono (cola de trabajos como queue_job de OCA, crons con lotes acotados, o un middleware externo) para no bloquear la UI ni superar limit_time_real, reintentos con backoff y límite, registro de cada mensaje (modelo propio de log de integración con payload, estado, error y número de intentos) y alertas al superar umbrales. También: transacciones pequeñas con commit explícito por lote, manejo de concurrencia (bloqueos, SELECT ... FOR UPDATE si es imprescindible), validación de datos antes de escribir, y pruebas de contrato con datos reales. En integraciones bidireccionales se define una fuente de verdad por campo para evitar ciclos de actualización.
Q59. ¿Cómo se integra Odoo con un data warehouse o herramientas de BI?
Opciones habituales: (1) lectura directa de PostgreSQL con un usuario de solo lectura y vistas o consultas SQL (rápido, pero acoplado al esquema interno, que cambia entre versiones); (2) extracción por API externa (search_read/read_group) hacia un ETL (Airflow, Fivetran, scripts Python) que carga un warehouse (BigQuery, Snowflake, Redshift); (3) CDC/réplica lógica de PostgreSQL (Debezium, réplicas de lectura) para latencias bajas; (4) exportaciones programadas a CSV/XLSX. Dentro de Odoo se pueden construir tableros con vistas pivot/graph y con Spreadsheet (Enterprise). Recomendaciones: modelar en capas (raw → staging → marts), documentar el mapeo de modelos clave (sale.order, account.move, stock.move), versionar las extracciones y aislar el reporting pesado del OLTP para no degradar la operación.
Q60. ¿Qué tipos de usuarios existen en Odoo?
Q61. ¿Cómo funcionan los grupos de seguridad (res.groups)?
Los grupos son el mecanismo central de permisos: cada app define grupos de nivel (por ejemplo sales.user propio, sales.manager, stock.user, account.group_account_invoice, account.group_account_manager, base.group_user, base.group_system, base.group_portal). Los grupos pueden tener implied_ids (heredan permisos de otros), categorías (selección exclusiva dentro de una app: usuario/manager) y usuarios. Se usan en: permisos de acceso a modelos (ir.model.access), reglas de registro (ir.rule), atributo groups de campos, vistas, menús y acciones, y en código con self.env.user.has_group('...'). La configuración se hace desde Ajustes con el modo desarrollador; en Enterprise también se gestionan con Studio. Buen diseño: pocos grupos propios, reutilizar los estándar y documentar la matriz rol-permiso.
Q62. ¿Qué son los access rights y las record rules?
Dos capas complementarias. Access rights (ir.model.access): permisos CRUD a nivel de modelo por grupo (read, write, create, unlink); se mantienen normalmente en security/ir.model.access.csv. Si no hay permiso para el modelo, la operación falla con AccessError sin importar el registro. Record rules (ir.rule): restricciones a nivel de registro, definidas con un dominio evaluado en el contexto del usuario, por ejemplo [('user_id','=',user.id)] (solo mis registros), [('company_id','in',company_ids)] (multi-compañía) o reglas por equipo de ventas; pueden ser globales (aplican a todos) o por grupo, y se combinan con OR dentro del mismo modelo y AND entre globales y de grupo. Odoo las aplica automáticamente a search/read/write/unlink, por lo que son la forma correcta de implementar visibilidad por rol sin filtrar en la UI.
Q63. ¿Cómo se protege el acceso a campos y vistas?
Con el atributo groups en campos, botones, páginas de notebook, menús y acciones: solo los usuarios de esos grupos los ven. En el formulario, el atributo se combina con invisible, readonly y required evaluados como expresiones Python sobre el registro y el contexto. Importante: la ocultación en la vista es cosmética; la protección real de datos sensibles se hace con record rules, access rights y validación en el servidor, porque un usuario con acceso al modelo puede leer campos vía API aunque la vista no los muestre. Para datos críticos (costes, márgenes, nómina) se usan grupos específicos y, si hace falta, campos company_dependent o modelos separados con permisos propios.
Q64. ¿Qué es sudo() y cuándo debe usarse con cuidado?
sudo() devuelve un recordset cuyo entorno usa el usuario administrador, saltándose access rights y record rules; with_user(user) y with_company(company)/with_context(...) cambian el usuario o el contexto de forma controlada. sudo() es legítimo en casos concretos: procesos automáticos (crons) que necesitan leer configuración, creación de registros desde el portal o el sitio web, y operaciones donde el usuario no tiene permisos pero la acción está autorizada por diseño. Riesgos: usarlo en métodos expuestos a la UI o a controladores puede permitir escalar privilegios o filtrar datos entre compañías. Reglas: minimizar el alcance (self.env['modelo'].sudo().browse(id).campo), nunca aplicar sudo() a un recordset que después se usa para escrituras sensibles, validar siempre los parámetros de entrada y documentar por qué se elevan permisos.
Q65. ¿Cómo se configura SSO y autenticación reforzada?
Odoo incluye auth_oauth para iniciar sesión con proveedores OAuth2 (Google, Microsoft/Entra ID, y cualquier IdP compatible configurando client id, secret y endpoints), y existen módulos para SAML 2.0/OIDC y para integración con LDAP (auth_ldap) en entornos corporativos. También soporta autenticación en dos pasos (TOTP con apps como Google Authenticator) activable por usuario u obligada por política. Para el acceso al portal y al sitio web se puede usar magic link/invitación por correo. Recomendaciones: centralizar identidades en el IdP corporativo, deshabilitar el alta libre de usuarios, forzar MFA a administradores y usuarios con permisos financieros, revisar periódicamente la lista de usuarios activos y sus claves de API, y registrar los intentos fallidos en el logging del proxy.
Q66. ¿Qué trazabilidad y auditoría ofrece Odoo?
El mixin mail.thread añade el chatter a cualquier modelo: mensajes, notas internas, seguidores y, con tracking=True en los campos, un historial de cambios con valor anterior y nuevo (mail.tracking.value). mail.activity.mixin registra actividades y asignaciones. Además: logs del servidor (nivel info/debug, con usuario y petición), logs de PostgreSQL, registros de acceso a documentos del portal, historial de trabajos cron y de las acciones automatizadas, y en Odoo.sh logs por entorno con retención. Para auditoría formal se suele complementar con: política de separación de funciones (quien crea un proveedor no aprueba su pago), bloqueo de fechas contables, informes de usuarios y permisos, y retención de backups. Los cambios de configuración sensibles conviene gobernarlos con proceso y aprobación.
Q67. ¿Qué prácticas de seguridad deben aplicarse en producción?
Q68. ¿Cómo funciona multi-compañía en Odoo?
Cada compañía es un registro res.company (asociado a un res.partner), con su moneda, plan contable, direcciones, datos fiscales y usuarios. Un usuario tiene una compañía principal y puede tener varias permitidas; el conmutador de la barra superior define el contexto allowed_company_ids. Los registros llevan company_id y las record rules multi-compañía restringen la visibilidad a las compañías del contexto. Existen compañías padre/hijo para jerarquías. Las operaciones entre empresas (ventas/compras intragrupo, transferencias entre almacenes de distintas compañías, notas de crédito cruzadas) se configuran con reglas y rutas específicas. Es una arquitectura de base de datos compartida con aislamiento lógico: más simple de operar que instancias separadas, pero exige rigor en la configuración de permisos.
Q69. ¿Qué cuidados requiere la configuración multi-compañía?
Puntos críticos: campos company_dependent (cuentas contables, listas de precio, responsables) para que cada empresa tenga su valor; check_company=True en relaciones Many2one para impedir mezclar registros de compañías distintas; record rules correctas en todos los modelos nuevos (si un modelo custom no las declara, los datos se filtran mal); diarios, secuencias y numeración por compañía; impuestos y posiciones fiscales por país/compañía; almacenes y ubicaciones asignados; monedas y tasas; y pruebas específicas de cada flujo con usuarios de una sola compañía. Errores frecuentes: documentos creados en la compañía equivocada por contexto heredado de un cron, y reportes consolidados mal interpretados. Se recomienda documentar la matriz de compañías/usuarios y validar con los responsables financieros antes del go-live.
Q70. ¿Cómo se gestionan los datos maestros y la deduplicación?
Los maestros clave son res.partner (contactos, con jerarquía padre-hijo, direcciones y tipo de contacto), product.product/product.template (con variantes, categorías, códigos internos y de proveedor/cliente, UoM), cuentas contables, impuestos, almacenes/ubicaciones, listas de precio y empleados. Buenas prácticas: definir dueño de cada maestro, reglas de alta (campos obligatorios, unicidad de NIF/documento, validación con VIES u OCR), política de variantes, categorías de producto alineadas con contabilidad y analítica, y limpieza previa a la migración (duplicados, inactivos, direcciones). Odoo trae herramientas de fusión de contactos duplicados y se pueden crear constraints SQL o acciones automatizadas para prevenir duplicados. La calidad del dato maestro determina el éxito del proyecto más que cualquier desarrollo.
Q71. ¿Cómo se importan y exportan datos masivamente?
Desde la UI: cualquier vista list tiene Importar (asistente con mapeo de columnas, detección de campos, previsualización y prueba en seco) y Exportar (selección de campos, inclusión de id externos, formatos CSV/XLSX). La clave es usar el id externo (External ID) para actualizaciones idempotentes y referencias cruzadas entre archivos (por ejemplo, importar productos con id propio y luego líneas que los referencian). Para volúmenes grandes o procesos repetidos: scripts con la API externa por lotes, carga directa con odoo-bin shell o CSV en data/ del módulo. Cuidados: orden de carga (maestros antes que transaccionales), validaciones y constraints (se ejecutan en cada create), rendimiento (lotes de miles de registros, desactivar crons y notificaciones durante la carga, mail_create_nolog en contexto) y plan de rollback. Siempre se prueba la importación en staging con datos reales antes del go-live.
Q72. ¿Cómo se afronta una migración de versión (upgrade) de Odoo?
Secuencia típica: (1) inventario: versión origen y destino, módulos custom, módulos de terceros (verificar disponibilidad en destino), integraciones, informes y volumen de datos; (2) limpiar la base (datos huérfanos, registros inútiles, módulos sin usar); (3) preparar entorno de prueba con copia de producción y ejecutar la migración (servicio de upgrade de Odoo para Enterprise, OpenUpgrade o scripts propios); (4) adaptar el código custom a los cambios de API/vistas/modelos de la versión destino (deprecaciones, campos renombrados, cambios en contabilidad e inventario son los más habituales); (5) pruebas de regresión funcionales y de integraciones, con usuarios clave; (6) plan de corte: congelación, dump final, migración, validación de saldos y existencias, y rollback definido; (7) estabilización post go-live. Los upgrades se presupuestan y planifican como proyecto, no como tarea técnica suelta.
Q73. ¿Qué es OpenUpgrade y cuándo conviene usarlo?
OpenUpgrade es el proyecto de la OCA que publica scripts de migración entre versiones para la edición Community: renombra/mueve tablas y campos, transforma datos y adapta la estructura para que una base de una versión anterior quede utilizable en la siguiente. Se ejecuta con módulos de migración y utilidades propias, en un entorno controlado y por saltos de versión soportados. Conviene cuando: se usa Community y no se quiere depender del servicio de pago de Odoo, se necesita auditoría y control del script, o hay bases muy personalizadas. El servicio de upgrade de Odoo (Enterprise) es la vía soportada en suscripciones: se sube la base, ellos ejecutan la migración y entregan un resultado para validar; incluye soporte para la prueba. En ambos casos el esfuerzo real suele estar en adaptar desarrollos propios y módulos de terceros, no en la migración del core.
Q74. ¿Cómo se implementa calidad: pruebas, linting y revisión de código?
Q75. ¿Cómo se configura odoo.conf y qué parámetros son críticos?
Parámetros principales: addons_path (rutas separadas por coma), db_host/db_port/db_user/db_password/db_name/dbfilter, data_dir (filestore y sesiones), http_port (8069) y gevent_port/longpolling_port (8072), workers y max_cron_threads, limit_memory_soft/limit_memory_hard, limit_time_cpu/limit_time_real, limit_request, proxy_mode, list_db, admin_passwd (contraseña maestra de gestión de bases: debe cambiarse y protegerse), logfile/log_level/log_handler, smtp_* (servidor de correo saliente, TLS/SSL), without_demo, server_wide_modules (por ejemplo web,web_kanban_gauge o módulos de monitoreo) y parámetros de rendimiento de PostgreSQL (db_maxconn). Todo lo sensible (contraseñas, claves) va en variables de entorno o gestor de secretos, no en repositorio.
Q76. ¿Cómo se dimensiona y afina el rendimiento?
Frentes: Aplicación: workers acorde a CPU/memoria (cada worker consume un registry por base cargada), límites de tiempo y memoria correctos, crons separados y con lotes acotados, evitar módulos inútiles, y código eficiente (operaciones en lote, read_group para agregados, prefetch, campos almacenados solo cuando se filtran, dominios indexados). Base de datos: PostgreSQL con shared_buffers, work_mem, effective_cache_size y maintenance_work_mem ajustados, max_connections coherente con db_maxconn y los workers, autovacuum activo y monitoreado, índices en campos de búsqueda frecuente, y análisis de consultas lentas (pg_stat_statements). Infraestructura: discos SSD/NVMe, nginx con cache de assets y compresión, filestore en almacenamiento rápido, CDN para el sitio web, y separación de BD y aplicación en servidores distintos cuando el volumen lo justifica. Datos: purga de logs, sesiones, adjuntos huérfanos y registros transient antiguos.
Q77. ¿Cómo se diagnostica un problema de lentitud?
Método: (1) caracterizar: ¿lentitud general o en una pantalla/proceso concreto?, ¿afecta a todos los usuarios o a uno, en qué horarios? (2) medir: logs con nivel debug/debug_sql para ver consultas y tiempos, tiempos de respuesta en nginx, métricas de CPU/memoria/IO del servidor, pg_stat_statements y EXPLAIN ANALYZE de las consultas sospechosas; en desarrollo, el profiler de Odoo (modo desarrollador) muestra tiempo por método y número de consultas. (3) causas frecuentes: N+1 por llamadas a search/browse dentro de bucles, campos computed sin almacenar recalculados en listados grandes, vistas kanban/pivot con datasets enormes, informes PDF con miles de registros, crons concurrentes, índices ausentes, adjuntos en disco lento, y locks o colisiones con la integración. (4) corregir por lotes, cachear, indexar y acotar dominios; después re-medir para comprobar la mejora.
Q78. ¿Cómo se gestionan backups y recuperación ante desastres?
Un backup completo de Odoo son dos piezas: el dump de PostgreSQL (pg_dump en formato custom o filestore incluido según herramienta) y el filestore (adjuntos y assets, en data_dir/filestore/<basededatos>). Sin el filestore faltan documentos e imágenes. Buenas prácticas: backups automáticos diarios (Odoo.sh los incluye; en on-premise con scripts, odoo-backup o herramientas del gestor), copia fuera del servidor y en otra región, cifrado, retención definida (por ejemplo 7 diarios, 4 semanales, 12 mensuales), verificación periódica restaurando en un entorno de pruebas y midiendo el tiempo. Definir RPO/RTO con el negocio, documentar el procedimiento de restauración y ensayarlo. En sistemas críticos, considerar réplica en caliente de PostgreSQL y snapshot de almacenamiento.
Q79. ¿Qué es Odoo.sh y cómo funciona su flujo de ramas y entornos?
Odoo.sh es la plataforma PaaS de Odoo conectada a un repositorio de GitHub: cada rama genera un build con su propia base de datos y entorno. Las ramas de desarrollo se etiquetan como development; una rama puede marcarse como staging (para pruebas con datos clonados de producción) y existe una rama de producción. La plataforma se encarga de: builds automáticos al hacer push, despliegue, workers y recursos configurables por entorno, backups diarios con descarga, logs por build, consola de correo saliente, SSH, editor en línea, monitoreo de rendimiento, actualizaciones de versión asistidas y dominios/certificados TLS. Facilita mucho el ciclo dev→test→prod sin montar infraestructura, con la contrapartida de menos control sobre el sistema operativo y de costos por workers/entornos.
Q80. ¿Cómo se hace CI/CD y despliegue fuera de Odoo.sh?
Alternativas habituales: Docker (imágenes oficiales de Odoo o propias con los addons), orquestadas con docker-compose o Kubernetes, montando addons y filestore en volúmenes persistentes y usando PostgreSQL externo; Ansible/Terraform para aprovisionar servidores, nginx y PostgreSQL y desplegar la versión del código; y pipelines de CI (GitHub Actions, GitLab CI, Jenkins) que: instalan dependencias, ejecutan linting (pylint-odoo, flake8), crean una base con --stop-after-init -i mis_modulos --test-enable, corren pruebas y publican artefactos. El despliegue a producción suele ser: merge a la rama release, etiqueta de versión, actualización del código en el servidor, -u de los módulos afectados, verificación de humo y rollback guardando el commit anterior y un dump previo. La inmutabilidad del contenedor y las migraciones versionadas son las claves para evitar entornos que «solo funcionan en producción».
Q81. ¿Cómo se monitorea y se da soporte a una instancia en producción?
Capas de monitoreo: infraestructura (CPU, memoria, disco, IO, red; Prometheus + Grafana, Datadog, CloudWatch o el panel de Odoo.sh), aplicación (logs con log_handler, errores 500, tiempos de respuesta por ruta, workers reiniciados por límites de memoria, jobs cron atrasados o fallidos, tamaño de la cola de correo), base de datos (conexiones activas, locks, consultas lentas, crecimiento de tablas, vacuum), y negocio (pedidos sin facturar, entregas bloqueadas, pagos no conciliados, interfaces con errores). Alertas con umbrales y canales (correo, Slack/Teams, PagerDuty). Soporte: mesa con niveles (funcional L1, técnico L2, proveedor L3), base de conocimiento, gestión de cambios con ventanas y aprobaciones, revisión periódica de usuarios/permisos y plan de actualizaciones de seguridad.
Q82. ¿Qué buenas prácticas de gobierno funcional y adopción recomiendas en un proyecto Odoo?
Pregunta típica: «¿Cuál es su experiencia con Odoo (ERP de gestión empresarial) en configuración, desarrollo, integraciones y administración?»
Apertura (sí + estructura): «Sí. He trabajado con Odoo [Community/Enterprise] versión [16/17/18] durante [X] años en proyectos de [sector], cubriendo tres frentes: configuración funcional de los módulos del ERP, desarrollo de módulos personalizados con Python y el ORM, y administración/integraciones en producción».
Configuración funcional: «He implementado flujos de [ventas, compras, inventario, manufactura y contabilidad]: rutas y reglas de reabastecimiento, lotes y trazabilidad, costeo [FIFO/AVCO] con valoración automática, localización contable de [país], posiciones fiscales, multi-compañía y analítica por [proyecto/centro de coste]».
Desarrollo: «Desarrollo módulos con la estructura estándar (models, views, security, data, wizards, controllers): modelos y campos computed almacenados, herencia de modelos y de vistas con xpath, reglas de registro por grupo, acciones automatizadas y crons, informes QWeb/PDF y componentes OWL cuando hace falta UI a medida. Uso el modo desarrollador, --dev=reload y pruebas con TransactionCase».
Integraciones: «He integrado Odoo con [SAP/NetSuite/Shopify/transportistas/pasarelas de pago/BI] usando la API externa XML-RPC/JSON-RPC con claves de API, controladores HTTP propios para webhooks, colas de trabajo con reintentos e idempotencia, y cargas masivas por importación y scripts».
Administración y seguridad: «Administro la plataforma: odoo.conf, workers y longpolling, nginx con TLS, PostgreSQL, backups (dump + filestore) con pruebas de restauración, y despliegue en [Odoo.sh / Docker / servidor propio]. En seguridad aplico mínimo privilegio con grupos y record rules, SSO/MFA, control de sudo() y trazabilidad con el chatter».
Cierre (resultados + aplicación al rol): «En mis proyectos logré [ejemplo cuantificado: reducir el cierre contable de X a Y días, automatizar N procesos, integrar N sistemas, disminuir errores de inventario en Z%]. En este rol aportaría [configuración funcional / desarrollo / arquitectura de integraciones] y ayudaría a priorizar estándar frente a customizaciones».
| Área | Qué mencionar | Impacto demostrable |
|---|---|---|
| Configuración funcional | Módulos implantados (ventas, compras, stock, MRP, contabilidad, CRM, POS), flujos order-to-cash y procure-to-pay, rutas, localización contable | Go-live por fases, procesos operando en producción, usuarios activos |
| Desarrollo de módulos | Modelos, herencias, vistas xpath, wizards, crons, informes QWeb, componentes OWL, módulos OCA | Repositorio con addons propios, módulos versionados y probados |
| Integraciones | XML-RPC/JSON-RPC con execute_kw, controladores y webhooks, colas, EDI/facturación electrónica, pagos y transportistas | Integraciones estables con log y reintentos, volumen de transacciones |
| Datos y migración | Limpieza e importación masiva (CSV/API), ids externos, migración de versión, OpenUpgrade | Migraciones exitosas, saldos y existencias cuadradas, downtime acotado |
| Contabilidad y finanzas | Plan contable, impuestos, conciliación bancaria, multi-moneda, analítica, activos y presupuestos | Cierre mensual más rápido, informes regulatorios al día |
| Seguridad | Grupos, access rights, record rules, SSO/MFA, multi-compañía, auditoría y hardening | Hallazgos remediados, matriz rol-permiso documentada |
| Administración | odoo.conf, workers, nginx/TLS, PostgreSQL, backups (dump + filestore), Odoo.sh/Docker | Disponibilidad, RTO/RPO cumplidos, restauraciones probadas |
| Rendimiento | Profiling, consultas N+1, índices, lotes, tuning de workers y PostgreSQL | Reducción medible de tiempos de respuesta o de duración de procesos |
| Referencia | Qué cubre |
|---|---|
| Documentación oficial de Odoo (odoo.com/documentation) | Guías de usuario por app, documentación de desarrollo (ORM, vistas, informes, seguridad), administración y tutoriales. |
| Código fuente en GitHub (odoo/odoo, odoo/enterprise) | Referencia definitiva de modelos, campos, vistas y métodos; útil para herencias y para entender flujos internos. |
| Odoo Community Association (odoo-community.org) | Miles de módulos gratuitos por dominio, guías de calidad y mantenibilidad, y repositorios de localizaciones. |
| OpenUpgrade (github.com/OCA/OpenUpgrade) | Scripts y documentación para migrar bases Community entre versiones. |
| Odoo.sh (odoo.sh) | Plataforma PaaS: ramas, builds, staging, backups, logs, SSH y despliegue continuo. |
| Odoo Apps Store (apps.odoo.com) | Catálogo de módulos comerciales y gratuitos de terceros con licencias por módulo. |
| Odoo eLearning / Academia (odoo.com/slides, scale-up) | Cursos oficiales por app y rutas funcionales, y certificaciones de Odoo. |
| Odoo Experience (evento anual) | Novedades de la versión anual, roadmap y talleres técnicos y funcionales. |
| Foro oficial de Odoo (odoo.com/forum) | Preguntas funcionales y técnicas respondidas por la comunidad y el equipo de Odoo. |
| Documentación de OWL (github.com/odoo/owl) | Framework de componentes del cliente web: hooks, servicios, plantillas y patches. |
| PostgreSQL Docs | Tuning (shared_buffers, work_mem), pg_stat_statements, vacuum y backups con pg_dump. |