HPL Apollo — Documentación de Módulos

Información General

ClienteHPL Apollo (Logistics)
Versión Odoo18.0 Enterprise
Última actualización2026-03-12
Módulos custompurchase_approval_kanak, crm_custom_fields
Repositoriohplapollo (rama main)


Índice

  1. purchase_approval_kanak — Flujo de Aprobación de OC
    1. Descripción Funcional
    2. Flujo de Trabajo
    3. Arquitectura Técnica
    4. Configuración
    5. Navegación
    6. Pruebas Funcionales
  2. crm_custom_fields — Campos Logísticos en CRM
    1. Descripción Funcional
    2. Arquitectura Técnica
    3. Navegación
    4. Pruebas Funcionales
  3. Dependencias y Arquitectura Global

1. purchase_approval_kanak

Multi-level purchase order approval workflow. Odoo 18 Enterprise. Versión 18.0.1.0.

1.1 Descripción Funcional

Este módulo añade un sistema de aprobación secuencial a las órdenes de compra. En lugar de que cualquier usuario pueda confirmar una OC directamente, el flujo obliga a que uno o varios aprobadores validen la OC según su importe y categoría del producto. Mientras está en aprobación, los campos clave de la OC quedan bloqueados para evitar modificaciones.

¿Cuándo se activa el flujo? Solo cuando en Ajustes se habilita "Purchase Order Approval By Rule" y se asigna una regla a la empresa. Sin esa configuración, las OCs funcionan igual que Odoo estándar.

Características principales:

  • Reglas de aprobación por rango de importe y categoría de producto
  • Aprobación secuencial: niveles inferiores deben aprobar antes que los superiores
  • Límites de gasto mensual por rol de aprobador
  • Notificaciones por email a cada aprobador cuando le toca actuar
  • Historial de aprobaciones y rechazos con motivo
  • Seguimiento de monto recibido vs pendiente por recepción (reception tracking)
  • Reporte PDF extendido con columna y totales de recepción

1.2 Flujo de Trabajo

BORRADOR
  │
  ├─ Sin sistema de aprobación activo:
  │      → Botón "Confirm Order" directo
  │
  └─ Con sistema de aprobación activo:
         [Usuario] → "Send For Approval"
              │
              ├─ Se generan instancias de approval.rules para esta OC
              ├─ Campos bloqueados (líneas, proveedor, fecha)
              └─ Email enviado al aprobador del nivel 1 (menor sequence)

         [Aprobador nivel 1] → "✅ Approve"
              │
              ├─ Marca su línea is_approved = True
              ├─ ¿Quedan niveles pendientes?
              │      Sí → notifica al siguiente aprobador
              └─      No → ready_for_po = True

         [Cualquier aprobador activo] → "❌ Reject"
              │
              ├─ Wizard: ingresar motivo de rechazo
              ├─ OC vuelve a BORRADOR (editable)
              └─ Se registra en historial

         [Usuario] → "Confirm Order" (solo si ready_for_po = True)
              └─ OC pasa a estado 'purchase' (orden confirmada)

1.3 Arquitectura Técnica

Modelos

ModeloTipoDescripción
purchase.orderExtensiónCampos de aprobación, reception tracking, visibilidad de botones, límites mensuales
purchase.order.approval.ruleNuevoPlantilla de regla a nivel empresa. Se configura en Ajustes.
purchase.order.approval.rule.linesNuevoLíneas de la plantilla: sequence, rol, rango de monto, límite mensual
purchase.order.approval.rulesNuevoInstancias de regla POR orden de compra. Se generan al enviar para aprobación.
purchase.order.approval.historyNuevoLog inmutable de acciones: quién, qué, cuándo, motivo de rechazo
approval.roleNuevoRoles de aprobación. Se asignan a empleados (Many2many).
approval.categNuevoCategorías de aprobación. Se asignan a productos.
hr.employeeExtensiónAñade campos: approval_role (Many2many), warehouse_id (Many2one)
product.templateExtensiónAñade campo: approval_category (Many2one approval.categ)
res.companyExtensiónAñade: purchase_order_approval (Boolean), purchase_order_approval_rule_id


Campos principales en purchase.order

CampoTipoDescripción
send_for_approvalBooleanTrue desde que se envía para aprobación
ready_for_poBoolean (computed)True cuando todos los niveles han aprobado
is_rejectedBooleanTrue si fue rechazada. Permite edición de campos.
show_confirm_buttonBoolean (computed)Oculta el botón Confirmar hasta que ready_for_po = True
show_send_approval_buttonBoolean (computed)Visible solo cuando la OC está en borrador y aún no enviada
show_approve_buttonBoolean (computed)Solo visible para el usuario con rol que coincide con el nivel activo
show_reject_buttonBoolean (computed)Solo visible para aprobadores del nivel activo
monthly_limit_warningChar (computed)Texto de alerta si el aprobador supera su límite mensual
monthly_limit_progressFloat (computed)Porcentaje de uso del límite mensual
approval_status_summaryHTML (computed)Resumen de estado de cada nivel con colores
amount_receivedMonetary (computed)Sum(qty_received × price_unit) por cada línea recibida
amount_pendingMonetary (computed)amount_total − amount_received
supplier_rep_idsMany2many res.usersRepresentantes del proveedor (campo adicional informativo)


Métodos clave en purchase.py

MétodoQué hace
_compute_approve_buttonDetermina qué usuario puede ver los botones Approve/Reject según su rol y el nivel activo
_compute_ready_for_poTrue si no quedan líneas de aprobación sin aprobar
_get_data_purchase_order_approval_rule_idsGenera las instancias de regla para una OC según su importe y categoría de productos
_get_monthly_spent / _get_monthly_spent_cachedCalcula el gasto mensual acumulado de un usuario. Usa SimpleCache con TTL 1 hora.
action_send_for_approvalTransición a estado "enviada para aprobación". Genera reglas y envía email nivel 1.
action_button_approveAprueba el nivel del usuario actual. Envía email al siguiente si aplica.
reject_purchaseAbre wizard de motivo de rechazo. Revierte OC a borrador.
action_refresh_approval_hierarchyRegenera las reglas de aprobación desde cero (útil si cambia la configuración).
_validate_monthly_limit_for_approvalVerifica si el aprobador excede su límite mensual antes de aprobar.


Valores especiales en configuración de reglas

  • -1 en límite inferior / superior = sin límite (aplica a cualquier monto)
  • -1 en monthly_purchase_limit = sin control de límite mensual
  • Los rangos del mismo sequence NO pueden solaparse. Odoo lanza error de validación.

Caché de gasto mensual

El cálculo de gasto mensual por aprobador usa un SimpleCache propio con TTL de 1 hora. Clave: user_id + company_id + mes. Se invalida automáticamente al cambiar el amount_total de cualquier OC.

Seguridad (ir.model.access.csv)

  • Managers: CRUD completo en todos los modelos de configuración
  • Users: solo lectura en modelos de configuración; lectura + escritura + creación (sin eliminar) en instancias de regla e historial por OC
  • Todos los usuarios pueden acceder a los wizards

1.4 Configuración

  1. Asignar roles a empleados: Empleados → [empleado] → pestaña RRHH → campo "Approval Role" (Many2many)
  2. Activar el sistema: Compras → Configuración → Ajustes → activar "Purchase Order Approval By Rule"
  3. Crear una regla: En el mismo Ajustes, crear o seleccionar una regla de aprobación con sus líneas:
    • Sequence: orden de aprobación (1 = primero)
    • Approval Role: qué rol aprueba este nivel
    • Lower Limit / Upper Limit: rango de monto. Usar -1 en Upper para "sin límite superior"
    • Monthly Limit: máximo mensual acumulado. Usar -1 para sin límite.
  4. (Opcional) Categorías por producto: Inventario → Productos → [producto] → campo "Approval Category"
  5. Verificar: Crear una OC de prueba y confirmar que aparece el botón "Send For Approval"

1.5 Navegación

AcciónRuta
Ver OCs pendientes de mi aprobaciónCompras → Aprobaciones → PO to Approve
Configurar reglas de aprobaciónCompras → Configuración → Ajustes → Aprobación de OC
Gestionar roles de aprobaciónCompras → Configuración → Approval Roles
Gestionar categorías de aprobaciónCompras → Configuración → Approval Categories
Ver jerarquía de una OCOC → pestaña "Approval Hierarchy"
Ver historial de acciones de una OCOC → pestaña "Approval History"
Ver monto recibido vs pendienteOC → pestaña "Reception Tracking"
Ver alertas de límite mensualOC → pestaña "Analytics"


1.6 Pruebas Funcionales

F1 — Flujo completo 1 nivel

  1. Crear regla con 1 línea: sequence=1, rol=Gerente, límites 0 a -1
  2. Asignar rol Gerente a un empleado/usuario
  3. Crear OC con importe > 0 → clic "Send For Approval"
  4. Iniciar sesión como Gerente → Compras → PO to Approve
  5. Esperar: botón "Approve" visible. Aprobar.
  6. Verificar: botón "Confirm Order" aparece en la OC

F2 — Flujo multi-nivel secuencial (2 niveles)

  1. Crear regla: sequence=1 (Supervisor, 0-5000) y sequence=2 (Gerente, 0 a -1)
  2. OC por 3000 → enviar para aprobación
  3. Iniciar sesión como Gerente: verificar que botón Approve NO aparece aún
  4. Iniciar sesión como Supervisor: aprobar
  5. Volver como Gerente: ahora sí aparece botón Approve. Aprobar.
  6. Verificar: OC lista para confirmar

F3 — Rechazo con motivo

  1. OC en aprobación → aprobador activo clic "❌ Reject"
  2. Ingresar motivo en el wizard → clic "Reject"
  3. Verificar: OC vuelve a borrador, campos editables
  4. Verificar: motivo registrado en pestaña "Approval History"

F4 — Bloqueo de edición durante aprobación

  1. OC enviada para aprobación (sin rechazar)
  2. Intentar editar líneas de productos, proveedor o fecha
  3. Verificar: campos bloqueados (readonly). Solo se desbloquean si la OC es rechazada.

F5 — Límite mensual

  1. Configurar línea de regla con monthly_purchase_limit = 10000
  2. Aprobar OCs hasta acumular >10000 en el mes con ese aprobador
  3. Nueva OC → enviar para aprobación
  4. Verificar: pestaña Analytics muestra alerta naranja con % de uso

F6 — Reception Tracking

  1. OC confirmada con recepciones parciales registradas
  2. OC → pestaña "Reception Tracking"
  3. Verificar: Monto Recibido = sum(qty_received × price_unit), Monto Pendiente = total − recibido
  4. Imprimir reporte PDF: verificar columna "Monto Recibido" por línea y filas de totales de recepción

F7 — Refresh de jerarquía

  1. OC en borrador o enviada → clic "🔄 Refresh Approval Hierarchy"
  2. Confirmar en el diálogo
  3. Verificar: líneas en pestaña "Approval Hierarchy" regeneradas con configuración actual

F8 — Validación de rangos solapados

  1. Compras → Configuración → Reglas de aprobación
  2. Crear dos líneas con el mismo sequence y rangos solapados (ej. 0-5000 y 3000-10000)
  3. Verificar: error "Overlapping amount ranges detected" al guardar

2. crm_custom_fields

Campos logísticos para oportunidades CRM. Odoo 18. Versión 18.0.1.0.

2.1 Descripción Funcional

Extiende las oportunidades de CRM con campos específicos para el negocio de transporte y logística de HPL Apollo. Permite registrar volúmenes cotizados, tarifas de venta y costo, y calcular automáticamente márgenes de ganancia (GP) para 5 tipos de servicio: flete aéreo, marítimo, terrestre, almacenamiento y aduanas.

Características principales:

  • Campos de cotización por tipo de flete con cálculo automático de margen
  • GP global semanal/mensual/anual (el anual actualiza el campo expected_revenue de la oportunidad)
  • Rutas de transporte (lanes) vinculadas a cada oportunidad
  • Asociación a ferias comerciales (tradeshows) y visitas de campo

2.2 Arquitectura Técnica

Modelos

ModeloTipoDescripción
crm.leadExtensiónTodos los campos logísticos por tipo de flete y GP global
crm.laneNuevoRutas de transporte (origen-destino)
crm.tradeshowNuevoFerias y eventos comerciales
crm.field_visitsNuevoVisitas de campo


Campos en crm.lead — GP Global

CampoTipoDescripción
estimated_gp_week_sharedFloatGP semanal total (entrada manual)
estimated_gp_month_sharedFloat (computed)= semanal × 4.33
estimated_gp_year_sharedFloat (computed)= mensual × 12. También escribe en expected_revenue.
actual_forwarderCharForwarder actual del cliente
lane_idsMany2many crm.laneRutas de transporte asociadas
commodity_detailTextDetalle de la mercancía
lead_sourceSelectionOrigen del lead
tradeshow_idMany2one crm.tradeshowFeria comercial asociada
field_visits_idMany2one crm.field_visitsVisita de campo asociada


Campos en crm.lead — Por Tipo de Flete

TipoVolumenSelling RateBuying/Airline RateMargen GP (computed)
Aéreoair_volume_per_week_kgsair_quoted_selling_rateair_quoted_airline_rateair_margin_expected_gp_kgs = selling − airline
Marítimosea_volume_per_week_teussea_quoted_selling_ratesea_quoted_buying_ratesea_margin_expected_gp_teu = selling − buying
Terrestreroad_volume_per_week_trailerroad_quoted_selling_rateroad_quoted_buying_rateroad_margin_expected_gp_trailer = selling − buying
Almacenamientowarehousing_volume_per_week_kgwarehousing_quoted_selling_ratewarehousing_cost_ratewarehousing_margin_expected_gp_kg = selling − cost
Aduanascustoms_quoted_selling_ratecustoms_cost_ratecustoms_margin_expected_gp = selling − cost


2.3 Navegación

AcciónRuta
Ver campos logísticos de una oportunidadCRM → Oportunidades → [oportunidad] → pestañas Aéreo / Marítimo / Terrestre / Almacenamiento / Aduanas
Ver GP calculadoCRM → [oportunidad] → sección "GP Global" (pestaña principal o lateral)
Gestionar rutas de transporteCRM → Configuración → Lanes
Gestionar ferias comercialesCRM → Configuración → Tradeshows
Gestionar visitas de campoCRM → Configuración → Field Visits


2.4 Pruebas Funcionales

F9 — Cálculo de GP por tipo de flete

  1. CRM → Oportunidades → nueva oportunidad
  2. Pestaña Aéreo: ingresar volume=100 kgs, selling_rate=5, airline_rate=3
  3. Verificar: air_margin_expected_gp_kgs = 2 (selling − airline)

F10 — GP global actualiza expected_revenue

  1. En la oportunidad, ingresar estimated_gp_week_shared = 1000
  2. Verificar: estimated_gp_month_shared = 4330 (×4.33)
  3. Verificar: estimated_gp_year_shared = 51960 (×12)
  4. Verificar: campo "Expected Revenue" de la oportunidad = 51960

F11 — Asociación de rutas (lanes)

  1. CRM → Configuración → Lanes → crear ruta "Lima → Miami"
  2. CRM → Oportunidades → [oportunidad] → campo Lane → asignar "Lima → Miami"
  3. Verificar: la ruta queda vinculada y visible en la oportunidad

3. Dependencias y Arquitectura Global

purchase_approval_kanak (v18.0.1.0)
    ← purchase (Odoo nativo)
    ← hr (Odoo nativo)
    ← stock (Odoo nativo)
    
    Extiende:
    → purchase.order       (workflow de aprobación + reception tracking)
    → hr.employee          (approval_role, warehouse_id)
    → product.template     (approval_category)
    → res.company          (configuración de reglas)
    → res.config.settings  (UI de ajustes)

crm_custom_fields (v18.0.1.0)
    ← base (Odoo nativo)
    ← crm (Odoo nativo)
    
    Extiende:
    → crm.lead             (campos logísticos y GP)
    
    Modelos nuevos:
    → crm.lane
    → crm.tradeshow
    → crm.field_visits

Los dos módulos son independientes entre sí.
Pueden instalarse por separado.

Documentación técnica HPL Apollo — ITC Services — 2026-03-12