⚡ Odoo Portal Desconectado
Invitado
Pestaña 1 (Python)
Consola de Resultados
Listo
// Esperando ejecución...
🔍 Explorador de Modelos & Campos Odoo
Nombre Técnico Etiqueta (String) Tipo de Campo Relación (Relation) Requerido Solo Lectura Acción
Ingresa un modelo y presiona "Explorar Campos".
⏱️ Tareas Programadas (ir.cron)
ID Nombre de la Tarea Estado Intervalo Próxima Ejecución Acción
Conéctate a una instancia para listar los cron jobs.
📦 Módulos Instalados & Actualización en Caliente
Nombre Técnico Descripción Versión Autor Acción
Haz clic en "Cargar Módulos" para inspeccionar.
⚙️ Parámetros del Sistema (ir.config_parameter)
Clave (Key) Valor (Value) Última Modificación Acción
Cargando parámetros...
📜 Historial de Comandos & Registro de Auditoría
Fecha Usuario Instancia / BD Modo Comando / Código Estado Commit Tiempo IP Acción
Cargando registros de auditoría...
👥 Usuarios y Roles del Portal
ID Usuario Nombre Rol Permisos Estado Acciones
Cargando usuarios...
🗄️ Bóveda de Instancias y Bases de Datos Odoo
ID Nombre URL Base de Datos Usuario Odoo Clave Guardada Descripción Acciones
Cargando instancias...
🔗 Instancias Asignadas por Usuario
Usuario del Portal Instancia Autorizada Acciones
Cargando asignaciones...
🔔 Notificaciones & Webhook de Auditoría (Slack / Discord / Telegram)
Se enviará una alerta automática cada vez que se realice una operación con Auto-Commit o comandos destructivos.
🤖 Configuración Centralizada del Asistente Copilot IA

📚 Guía Oficial y Casos de Uso del Portal

Referencia exhaustiva de comandos normalizados, mejores prácticas de Odoo XML-RPC y casos de uso desde nivel básico hasta scripts complejos de lote.

⚡ Referencia Rápida de Comandos Normalizados
1. search_read(model, domain, fields, limit)
Busca y extrae diccionarios con los campos indicados. limit=None para todos.
2. search_count(model, domain)
Retorna el número entero de registros que coinciden con el dominio.
3. write(model, ids, values_dict)
Actualiza uno o varios IDs de una sola llamada. Aplica commit de forma nativa.
4. create(model, values_dict)
Crea un registro y devuelve el nuevo ID entero generado en la base de datos.
5. unlink(model, ids)
Elimina permanentemente los registros identificados por los IDs indicados.
6. read_group(model, domain, fields, groupby)
Agrupaciones agregadas de base de datos con sumatorias o promedios.
7. call(model, method, ids, *args, **kwargs)
Invoca botones y métodos de lógica de negocio (ej: action_post).
8. get_xml_id / get_by_xml_id
Traduce IDs numéricos a External IDs (XML IDs) y viceversa.
🟢 1. Casos de Uso Básicos (Consultas & Lecturas Directas)
Caso 1.1: Consultar clientes activos con campos específicos

Obtiene los primeros 15 contactos marcados como empresa junto con su RIF/NIF y correo:

search_read(
    'res.partner',
    [('is_company', '=', True), ('active', '=', True)],
    ['id', 'name', 'vat', 'email', 'phone'],
    limit=15
)
Caso 1.2: Contar facturas en estado Borrador vs Publicadas

Compara la cantidad de registros usando search_count:

borradores = search_count('account.move', [('state', '=', 'draft')])
publicadas = search_count('account.move', [('state', '=', 'posted')])

result = {
    'facturas_borrador': borradores,
    'facturas_publicadas': publicadas,
    'total': borradores + publicadas
}
Caso 1.3: Inspeccionar la estructura de campos de un modelo

Permite descubrir nombres técnicos, tipos y relaciones antes de hacer escrituras:

fields_get('material.purchase.requisition', ['state', 'requisition_type', 'company_id', 'line_ids'])
🟡 2. Casos de Uso Intermedios (Escritura, Creación & Agrupaciones)
Caso 2.1: Actualizar una Requisición de Materiales

Modifica de forma directa el tipo de requisición y la compañía asociada:

write('material.purchase.requisition', 21101, {
    'company_id': 12,
    'requisition_type': 'service',
    'name': 'RAGICA00016383'
})
Caso 2.2: Crear un nuevo Cliente o Proveedor

Crea el registro y guarda el nuevo ID:

partner_id = create('res.partner', {
    'name': 'Tecnología & Soluciones Globales C.A.',
    'is_company': True,
    'vat': 'J-12345678-9',
    'email': 'contacto@tecnosoluciones.com',
    'comment': 'Creado vía Odoo Remote Portal'
})

result = f"Contacto creado exitosamente con ID: {partner_id}"
Caso 2.3: Agrupación & Sumatoria de Facturación por Cliente

Usa read_group para sumar totales agrupados por partner_id:

read_group(
    'account.move',
    [('state', '=', 'posted'), ('move_type', '=', 'out_invoice')],
    ['amount_total:sum', 'amount_untaxed:sum'],
    ['partner_id'],
    limit=10,
    orderby='amount_total desc'
)
🔥 3. Casos de Uso Complejos (Operaciones en Lote, Filtrado & Métodos)
Caso 3.1: Buscar y Actualizar en Lote todas las líneas de una Requisición

Extrae todas las líneas (con limit=None) que cumplan una condición y las actualiza masivamente con una sola llamada atómica:

# 1. Extraer todas las líneas asociadas a la requisición
lines = search_read(
    'material.purchase.requisition.line',
    [('requisition_id', '=', 21225), ('requisition_type', '=', 'internal')],
    ['id'],
    limit=None
)
line_ids = [l['id'] for l in lines]

# 2. Actualizar tipo a 'purchase' en lote
if line_ids:
    write('material.purchase.requisition.line', line_ids, {'requisition_type': 'purchase'})
    result = f"✅ Se actualizaron con éxito {len(line_ids)} líneas: {line_ids}"
else:
    result = "⚠️ No se encontraron líneas internas para esta requisición."
Caso 3.2: Ejecutar Botón / Método de Negocio de Odoo en Lote

Invoca un método nativo del modelo (ej: action_post o action_confirm):

# Buscar facturas en borrador listas para validar
moves = search_read('account.move', [('state', '=', 'draft'), ('move_type', '=', 'out_invoice')], ['id'], limit=5)
move_ids = [m['id'] for m in moves]

if move_ids:
    # Invocar método action_post
    call('account.move', 'action_post', move_ids)
    result = f"Facturas validadas exitosamente: {move_ids}"
else:
    result = "No hay facturas pendientes."
Caso 3.3: Limpieza y Eliminación Segura de Líneas Huérfanas

Busca registros sin padre o sin referencias y los elimina de forma controlada:

# Buscar líneas sin pedido asociado
orphan_lines = search_read(
    'purchase.order.line',
    [('order_id', '=', False)],
    ['id'],
    limit=50
)
ids_to_delete = [r['id'] for r in orphan_lines]

if ids_to_delete:
    unlink('purchase.order.line', ids_to_delete)
    result = f"🗑️ Se eliminaron {len(ids_to_delete)} líneas huérfanas: {ids_to_delete}"
else:
    result = "No se encontraron líneas huérfanas."
Caso 3.4: Buscar un Registro por su External ID (XML ID)

Encuentra el ID numérico a partir del XML ID del módulo:

# 1. Obtener ID del diario de ventas principal
journal_info = get_by_xml_id('account.sales_journal')

# 2. O consultar el XML ID a partir del ID de un partner
partner_xml_id = get_xml_id('res.partner', 1)

result = {
    'journal_info': journal_info,
    'partner_xml_id': partner_xml_id
}