Guía Completa del Ciclo de Vida del Producto
Esta guía proporciona un recorrido completo del ciclo de vida del producto en OmniCRM, desde la creación de una definición de producto hasta la provisión de servicios, la adición de complementos y la desprovisión. Cubriremos la estrategia de precios, la integración de Ansible y proporcionaremos ejemplos del mundo real a lo largo del documento.
Descripción general: El viaje del producto al servicio
El ciclo de vida de un producto en OmniCRM sigue estas etapas:
- Definición del Producto - El administrador crea una plantilla de producto con reglas de precios y provisión.
- Creación del Servicio - El cliente ordena el producto, el sistema provisiona la instancia del servicio.
- Ciclo de Vida del Servicio - El cliente utiliza el servicio, añade complementos/recargas, modifica el servicio.
- Desprovisión - El servicio es terminado, los recursos son liberados.
Comprendiendo los Precios: Mayorista vs Minorista
Cada producto y servicio en OmniCRM tiene dos dimensiones de precios: mayorista y minorista.
Costo Mayorista
El costo mayorista representa el costo real para entregar el servicio:
- Costos de infraestructura y ancho de banda
- Tarifas de licencia
- Costos de equipo
- Gastos operativos
Costo Minorista
El costo minorista es el monto cobrado al cliente.
Costos de Configuración
Tanto mayorista como minorista tienen variantes de costo de configuración para cargos de provisión únicos:
wholesale_setup_cost- Su costo para la provisión.retail_setup_cost- Monto cobrado al cliente por la activación.
Ejemplo:
{
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00
}
Etapa 1: Creación de una Definición de Producto
Los productos son plantillas que definen qué se provisiona y cómo se cobra a los clientes.
Creando un Producto de SIM Móvil
Vamos a crear un producto de SIM móvil prepago con 20GB de datos por mes.
Paso 1: Navegar a la Gestión de Productos
Desde la interfaz de administración, vaya a Productos → Crear Producto.
Paso 2: Definir Información Básica
{
"product_name": "Prepaid Mobile 20GB",
"product_slug": "prepaid-mobile-20gb",
"category": "standalone",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-sim-card",
"comment": "Prepaid mobile SIM with 20GB data, unlimited calls & texts"
}
Explicaciones de Campos:
product_name- Nombre visible para el cliente mostrado en el catálogo.product_slug- Identificador seguro para URL utilizado en llamadas API y enlaces.category- "standalone" significa que esto crea un nuevo servicio (vs complemento/paquete).service_type- Agrupa productos relacionados, utilizado para el filtrado de complementos.enabled- Debe ser verdadero para que el producto sea ordenable.icon- Icono de FontAwesome mostrado en la interfaz de usuario.comment- Notas internas para referencia del personal.
Paso 3: Establecer Precios
{
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00,
"contract_days": 30
}
Desglose de Precios:
- Ingresos mensuales por cliente: £15.00
- Costo mensual para entregar: £5.00
- Margen de beneficio mensual: £10.00 (200% de margen, 67% de margen)
- Beneficio de configuración: -£1.00 (subvencionado para atraer clientes)
- Duración del contrato: 30 días (renovación mensual)
Paso 4: Definir Elegibilidad del Cliente
{
"residential": true,
"business": false,
"customer_can_purchase": true,
"available_from": "2025-01-01T00:00:00Z",
"available_until": null
}
- Los clientes residenciales pueden ordenar.
- Los clientes comerciales no pueden (línea de productos diferente).
- Compra de autoservicio habilitada.
- Disponible desde el 1 de enero de 2025 en adelante.
- Sin fecha de finalización (oferta continua).
Paso 5: Configurar Renovación Automática
{
"auto_renew": "prompt",
"allow_auto_renew": true
}
"prompt"- Preguntar al cliente si desea la renovación automática al momento de la compra."true"- Renovar automáticamente sin preguntar."false"- Nunca renovar automáticamente (solo recarga manual).allow_auto_renew: true- El cliente puede habilitar/deshabilitar la renovación automática más tarde.
Paso 6: Especificar Requisitos de Inventario
Los requisitos de inventario definen qué recursos físicos o virtuales deben ser asignados al provisionar este producto. Este es un paso crítico que conecta su catálogo de productos con su Sistema de Gestión de Inventario.
{
"inventory_items_list": "['SIM Card', 'Mobile Number']"
}
¿Qué Son los Artículos de Inventario?
Los artículos de inventario son recursos rastreables almacenados en el sistema de inventario de OmniCRM. Cada artículo tiene:
- Tipo - Definido por la Plantilla de Inventario (por ejemplo, "SIM Card", "Mobile Number", "Modem").
- Atributos únicos - Números de serie, direcciones MAC, números de teléfono, etc.
- Estado - En stock, asignado, desmantelado, etc.
- Ubicación - Ubicación física o lógica.
Cómo Funcionan los Requisitos de Inventario:
La inventory_items_list es una lista de Python (como una cadena) que contiene nombres de tipos de inventario. Cada nombre debe coincidir exactamente con un nombre existente de Plantilla de Inventario.
Ejemplo de Requisitos de Inventario:
# Producto de SIM móvil
inventory_items_list: "['SIM Card', 'Mobile Number']"
# Servicio de internet fijo
inventory_items_list: "['Modem Router', 'Static IP Address']"
# Servicio digital (sin artículos físicos)
inventory_items_list: "[]"
# Inalámbrico fijo con CPE
inventory_items_list: "['Fixed Wireless CPE', 'IPv4 Address', 'IPv6 Prefix']"
El Proceso del Selector de Inventario
Cuando un usuario provisiona un producto con requisitos de inventario, el sistema impone un proceso de selección obligatorio:
1. Botón de Provisión Habilitado
Después de seleccionar el producto, el usuario hace clic en "Provisionar". En lugar de provisionar inmediatamente, el sistema verifica inventory_items_list.
2. Modal del Selector de Inventario Aparece
Si se requiere inventario, aparece un cuadro de diálogo modal con un menú desplegable separado para cada tipo de inventario:
3. Filtrando Inventario Disponible
El menú desplegable para cada tipo de inventario solo muestra artículos que son:
- Tipo Correcto - Coincide exactamente con el nombre de la plantilla de inventario.
- Estado Disponible -
item_statees "Nuevo" o "En Stock" (no "Asignado" o "Dañado"). - No Asignado -
service_idycustomer_idson NULL. - En Stock en Ubicación - Opcionalmente filtrado por ubicación de almacén/tienda.
Ejemplo de Opciones del Menú Desplegable:
Para el tipo de inventario "SIM Card", el menú desplegable podría mostrar:
Cada opción muestra:
- ID de inventario o número de referencia.
- Identificador principal (
itemtext1- por ejemplo, ICCID para SIM, número para teléfono). - Ubicación actual (
item_location).
4. Selección Requerida para Proceder
Regla Crítica: La provisión NO puede proceder sin seleccionar todos los artículos de inventario requeridos.
- El botón "Continuar" está deshabilitado hasta que todos los menús desplegables tengan selecciones.
- El usuario debe seleccionar un artículo para cada tipo de inventario.
- El sistema valida las selecciones antes de proceder.
5. Inventario Seleccionado Pasado a Ansible
Una vez que el usuario hace clic en "Continuar", los IDs de inventario seleccionados se pasan al libro de jugadas de Ansible como variables:
# Usuario seleccionado:
# - SIM Card inventory_id: 5001
# - Mobile Number inventory_id: 5002
# Variables pasadas a Ansible:
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001, # ID de Inventario
"Mobile Number": 5002, # ID de Inventario
"access_token": "eyJ..."
}
Nota: El nombre de la variable coincide exactamente con el tipo de inventario. El libro de jugadas utiliza hostvars[inventory_hostname]['SIM Card'] para acceder al ID de inventario.
6. El Libro de Jugadas Obtiene Detalles Completos del Inventario
El libro de jugadas de Ansible utiliza el ID de inventario para obtener detalles completos:
- name: Get SIM Card details from inventory
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_sim
- name: Extract ICCID and IMSI
set_fact:
iccid: "{{ api_response_sim.json.itemtext1 }}"
imsi: "{{ api_response_sim.json.itemtext2 }}"
Ahora el libro de jugadas tiene todos los detalles de la SIM (ICCID, IMSI, etc.) para provisionar al suscriptor en el HSS.
7. Estado del Inventario Cambiado a "Asignado"
Después de que se crea el registro del servicio, el libro de jugadas actualiza el inventario para vincularlo al servicio:
- name: Assign SIM Card to Service
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body:
{
"service_id": "{{ service_creation_response.json.service_id }}",
"customer_id": "{{ customer_id }}",
"item_state": "Assigned"
}
Importante: La asignación de inventario ocurre durante la ejecución del libro de jugadas como una tarea específica, NO cuando se hace clic en el botón de provisión. Esto significa:
- Riesgo de Doble Asignación: Entre hacer clic en "Provisionar" y que el inventario sea asignado, otro usuario podría teóricamente seleccionar el mismo artículo de inventario.
- Mejor Práctica: Para operaciones de alto volumen, implemente bloqueo de inventario o use transacciones de base de datos.
- Rollback en Caso de Fallo: Si el libro de jugadas falla antes de la asignación de inventario, el inventario permanece no asignado y disponible para reutilización.
¿Por qué no asignar antes?
El inventario no se asigna cuando se hace clic en "Provisionar" porque:
- Se Necesita el ID del Servicio: El
service_idno existe hasta que el servicio se crea en el libro de jugadas. - Simplicidad de Rollback: Si la provisión falla temprano (por ejemplo, falla en la creación de la cuenta OCS), no se necesita limpieza del inventario.
- Flexibilidad: El libro de jugadas puede decidir no asignar inventario basado en lógica condicional.
Manejo de Provisiones Fallidas:
Cuando una provisión falla después de que el inventario ha sido asignado, el bloque de rescate debe liberar el inventario:
rescue:
- name: Release inventory on failure
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body:
{
"service_id": null,
"customer_id": null,
"item_state": "In Stock"
}
when: service_id is defined # Solo si se creó el servicio
Esto asegura que el inventario no quede en un estado "Asignado" para un servicio inexistente o fallido.
Cuando la Lista de Inventario está Vacía
Si inventory_items_list: "[]" (lista vacía), el selector de inventario se omite por completo y la provisión procede inmediatamente. Esto es común para:
- Productos digitales - Licencias de software, cuentas VPN.
- Complementos de servicio - Recargas de datos que no necesitan nuevo hardware.
- Servicios virtuales - Que no consumen recursos rastreables.
Ejemplo: Un complemento de "5GB Data Boost" tiene inventory_items_list: "[]" porque solo agrega saldo a un servicio existente sin necesidad de nuevo hardware.
Configuración de Plantilla de Inventario
Antes de usar un tipo de inventario en inventory_items_list, debe crear la Plantilla de Inventario:
- Navegue a Administración → Inventario → Plantillas.
- Cree una plantilla con el nombre exacto (por ejemplo, "SIM Card").
- Defina los campos:
itemtext1_label: "ICCID".itemtext2_label: "IMSI".itemtext3_label: "PUK Code".
- Agregue artículos de inventario de este tipo al stock.
Para obtener detalles completos sobre cómo crear y gestionar plantillas de inventario, consulte Gestión de Inventario.
Múltiples Artículos del Mismo Tipo
Si bien inventory_items_list es un arreglo, tener tipos duplicados (por ejemplo, "['SIM Card', 'SIM Card']") no se recomienda ya que puede causar confusión en la interfaz de usuario y en la nomenclatura de variables del libro de jugadas.
Para escenarios que requieren múltiples artículos similares:
Opción 1: Crear nombres de plantillas de inventario distintos
# Servicio de teléfono Dual-SIM
inventory_items_list: "['Primary SIM Card', 'Secondary SIM Card', 'Mobile Number']"
Cree plantillas separadas: "Primary SIM Card" y "Secondary SIM Card" con los mismos campos pero diferentes nombres.
Opción 2: Usar un solo artículo de inventario agrupado
# Kit Dual-SIM
inventory_items_list: "['Dual SIM Kit', 'Mobile Number']"
Donde la plantilla de inventario "Dual SIM Kit" tiene campos para ambas SIMs (itemtext1: ICCID Primario, itemtext2: ICCID Secundario, etc.).
Escenarios Comunes de Inventario
Servicio Móvil:
inventory_items_list: "['SIM Card', 'Mobile Number']"
- SIM Card: Física o eSIM con ICCID/IMSI.
- Mobile Number: Número de teléfono (MSISDN).
Internet Fijo:
inventory_items_list: "['Modem Router', 'Static IP Address']"
- Modem Router: Dispositivo CPE con dirección MAC.
- Static IP Address: IPv4 del grupo de direcciones.
Inalámbrico Fijo:
inventory_items_list: "['Fixed Wireless CPE', 'IPv4 Address', 'IPv6 Prefix']"
- CPE: Equipo de instalaciones del cliente (antena, módem).
- IPv4: Dirección IP pública.
- IPv6 Prefix: prefijo /56 o /64.
Nota: Las citas y la programación no son artículos de inventario. Utilice sistemas de programación/calendario separados para citas de instalación.
Servicio VoIP:
inventory_items_list: "['DID Number']"
- DID Number: Número de teléfono de Marcación Directa.
Nota: Los nombres de usuario SIP, contraseñas y configuraciones de cuentas son generados programáticamente por el libro de jugadas de provisión, no seleccionados del inventario.
GPON/Fibra:
inventory_items_list: "['ONT Device', 'GPON Port', 'IPv4 Address', 'Fiber Drop Cable']"
- ONT Device: Terminal de Red Óptica con número de serie.
- GPON Port: Puerto específico en OLT con conexión de fibra.
- IPv4 Address: IP pública o privada.
- Fiber Drop Cable: Cable de fibra física de la calle a las instalaciones (rastreado para gestión de activos).
Alquiler de Equipos:
inventory_items_list: "['Rental Modem']"
- Rastrear qué módem está con qué cliente.
- Importante para recuperar equipos en caso de cancelación.
Por qué Importan los Requisitos de Inventario
1. Prevenir Doble Asignación
Sin seguimiento de inventario, podría accidentalmente:
- Asignar la misma tarjeta SIM a dos clientes.
- Asignar la misma dirección IP a múltiples servicios.
- Enviar el mismo número de serie de equipo a diferentes ubicaciones.
El selector de inventario asegura que cada artículo esté asignado a exactamente un servicio.
2. Registro de Auditoría
La asignación de inventario crea un registro de auditoría completo:
- Qué tarjeta SIM está con qué cliente.
- Cuándo fue asignada.
- Qué servicio está utilizando qué número de teléfono.
- Historial de equipos (quién lo tuvo, cuándo, para qué servicio).
3. Planificación de Recursos
Rastrear niveles de inventario:
- Alertar cuando las tarjetas SIM estén bajas.
- Reordenar antes de que se agoten.
- Planificar horarios de técnicos según la disponibilidad de CPE.
- Gestionar la asignación de espacio de direcciones IP.
4. Seguimiento de Costos
Vincular el costo mayorista a un artículo específico:
- Rastrear el costo de cada tarjeta SIM.
- Calcular la depreciación del equipo.
- Identificar artículos perdidos o robados.
- COGS (Costo de Bienes Vendidos) preciso.
5. Desprovisión
Cuando se cancela el servicio, el inventario puede ser:
- Liberado de nuevo al stock (tarjetas SIM, módems).
- Retirado (equipo dañado).
- Devuelto al proveedor (equipo de alquiler).
- Conservado por un período de gracia (números de teléfono antes de la liberación).
Resolución de Problemas del Selector de Inventario
Problema: Aparece el mensaje "No hay inventario disponible".
Causas:
- No existen artículos de inventario del tipo requerido en la base de datos.
- Todos los artículos ya están "Asignados" a otros servicios.
- Los artículos están marcados como "Dañados" o "Fuera de Servicio".
- El nombre de la plantilla de inventario no coincide exactamente (sensible a mayúsculas).
Solución:
- Verifique que la plantilla de inventario exista: Administración → Inventario → Plantillas.
- Verifique que el nombre de la plantilla coincida exactamente (incluyendo espacios, mayúsculas).
- Agregue artículos de inventario de este tipo: Administración → Inventario → Agregar Artículo.
- Verifique que los artículos estén en estado "Nuevo" o "En Stock".
- Verifique que los artículos no estén ya asignados (
service_iddebe ser NULL).
Problema: El selector de inventario no aparece.
Causas:
inventory_items_listestá vacío:"[]".inventory_items_listes NULL o no está configurado.- La categoría del producto es "complemento" y hereda el inventario del servicio padre.
Solución:
- Si se necesita inventario, establezca
inventory_items_list: "['Type1', 'Type2']". - Verifique que la definición del producto se haya guardado correctamente.
- Verifique que la respuesta de la API para el producto incluya
inventory_items_list.
Problema: El libro de jugadas falla con "inventario no encontrado".
Causas:
- El libro de jugadas hace referencia al nombre de variable incorrecto.
- El ID de inventario no se pasó correctamente.
- El inventario fue eliminado entre la selección y la provisión.
Solución:
- Verifique que el libro de jugadas use la variable correcta:
hostvars[inventory_hostname]['SIM Card']. - Verifique que la variable sea un entero:
{{ hostvars[inventory_hostname]['SIM Card'] | int }}. - Agregue manejo de errores en el libro de jugadas para inventario faltante.
Consulte Gestión de Inventario para obtener detalles completos sobre cómo crear plantillas, agregar artículos y gestionar niveles de stock.
Paso 7: Definir Características y Términos
Las características y términos son contenido de marketing y legal visible para el cliente que ayuda a los clientes a entender lo que están comprando y las obligaciones involucradas.
{
"features_list": "20GB High-Speed Data. Unlimited Calls & Texts. EU Roaming Included. No Contract. 30-Day Expiry",
"terms": "Credit expires after 30 days. Data, calls, and texts valid only within expiry period. Fair use policy applies. See website for full terms."
}
Propósito y Valor Comercial
Lista de Características - Marketing y Ventas:
La lista de características cumple múltiples funciones comerciales críticas:
- Diferenciación del Producto - Ayuda a los clientes a comparar rápidamente productos y elegir el correcto.
- "Prepaid Mobile 20GB" vs "Prepaid Mobile 50GB" - las características muestran claramente la diferencia.
- Sin características, los clientes solo ven el precio, perdiendo la propuesta de valor.
- Comunicación de Marketing - Puntos de venta clave mostrados de manera prominente.
- "EU Roaming Included" atrae a viajeros internacionales.
- "No Contract" apela a clientes reacios a compromisos.
- Las características impulsan decisiones de compra.
- Expectativas del Cliente - Establece expectativas claras sobre lo que está incluido.
- Reduce llamadas de soporte ("¿Esto incluye llamadas?" → claramente listado).
- Previene malentendidos y solicitudes de reembolso.
- Genera confianza a través de la transparencia.
- Autoservicio - Permite a los clientes seleccionar productos apropiados por sí mismos.
- El cliente lee las características, entiende la oferta, toma una decisión informada.
- Reduce la necesidad de explicación por parte del personal de ventas.
- Acelera el proceso de compra.
- SEO y Descubribilidad - Las características pueden ser indexadas para búsqueda.
- El cliente busca "plan móvil de llamadas ilimitadas" → el producto aparece.
- Mejora la buscabilidad del catálogo de productos.
Términos y Condiciones - Legal y Cumplimiento:
Los términos sirven para propósitos legales y operativos:
- Protección Legal - Protege al negocio de disputas y responsabilidad.
- "El crédito expira después de 30 días" - el cliente no puede exigir un reembolso a los 31 días.
- "Se aplica política de uso justo" - previene abusos (compartir toda la oficina en un plan móvil).
- Crea un acuerdo vinculante.
- Gestión de Expectativas - Previene la insatisfacción del cliente.
- "Válido solo dentro del período de expiración" - el cliente conoce la fecha límite de uso.
- "No puede ser reembolsado" (para complementos) - previene compras fraudulentas.
- Reduce contracargos y quejas.
- Cumplimiento Regulatorio - Cumple con requisitos legales.
- Las leyes de protección al consumidor requieren términos claros.
- Las regulaciones de telecomunicaciones exigen divulgación.
- Se pueden hacer referencia a términos de GDPR/privacidad.
- Límites Operativos - Define el alcance y las limitaciones del servicio.
- "Sujeto a cobertura de red" - no es responsable por zonas muertas.
- "La velocidad puede variar" - gestiona expectativas sobre velocidades "hasta".
- "El equipo debe ser devuelto" - asegura la recuperación del equipo de alquiler.
- Registro de Auditoría - Prueba que el cliente fue informado.
- El cliente aceptó los términos al momento de la compra.
- El sistema registra la marca de tiempo de aceptación.
- Defendible en disputas o procedimientos legales.
Ejemplo del Mundo Real:
El cliente compra un plan "Llamadas y Textos Ilimitados", luego lo usa para telemarketing (10,000 llamadas/día). Sin términos:
- Cliente: "¡Dijiste ilimitado!"
- Proveedor: "Nos referíamos a uso personal..."
- Cliente: "¡Eso no es lo que publicitaste!"
- Resultado: Disputa, posible queja ante el regulador, daño a la marca.
Con términos: "Se aplica política de uso justo. El servicio es solo para uso personal. Uso comercial prohibido."
- Proveedor: Señala los términos que el cliente aceptó.
- El cliente no puede alegar ignorancia.
- Base legal para suspender el servicio.
- Disputa resuelta a favor del proveedor.
Formato de la Lista de Características:
Entender el formato correcto es crítico porque un formato incorrecto rompe la visualización de la interfaz de usuario. Las características pueden aparecer como una larga cadena en lugar de puntos de viñeta, o no mostrarse en absoluto.
El campo features_list se puede formatear de dos maneras:
Opción 1: Cadena Separada por Puntos (Recomendado)
Las características están separadas por un punto y un espacio (". "). La interfaz de usuario se divide en este delimitador y renderiza cada característica como un punto de viñeta.
¿Por qué este formato?
- Simple de editar: solo escriba características con puntos entre ellas.
- Sin caracteres especiales que escapar.
- Funciona de manera confiable en todos los componentes de la interfaz de usuario.
- Fácil de actualizar sin romper la sintaxis JSON.
Correcto vs Incorrecto:
Opción 2: Cadena de Arreglo JSON
"['20GB High-Speed Data', 'Unlimited Calls & Texts', 'EU Roaming Included']"
La interfaz de usuario también puede analizar arreglos JSON. Tenga en cuenta que esto es una cadena que contiene JSON, no un arreglo JSON real en la base de datos.
¿Por qué existe este formato?
- Permite características con puntos en ellas (por ejemplo, "Hasta 100Mbps. Sujeto a disponibilidad.").
- La generación programática desde scripts/API es más fácil.
- Importado de catálogos de productos externos que utilizan arreglos.
Importante: Esto debe ser una sintaxis válida de lista de Python como cadena. Comillas simples alrededor de cada elemento, comillas dobles alrededor de toda la cadena.
¿Qué Formato Usar?
- Separado por puntos - Para la creación manual de productos en la interfaz de usuario (más simple, menos propenso a errores).
- Arreglo JSON - Para la creación de productos basada en API/script (más robusto para características complejas).
Ambos formatos producen una salida idéntica en la interfaz de usuario; solo afectan cómo se ingresan los datos.
Dónde Aparecen las Características en la Interfaz de Usuario:
1. Catálogo de Productos (Vista del Cliente)
Cuando los clientes navegan por los productos disponibles, las características se muestran como puntos de viñeta en cada tarjeta de producto:
2. Página de Detalles del Producto
Al hacer clic en "Ver Detalles" se muestra la información completa del producto, incluyendo:
- Nombre del producto e icono.
- Precios (costo mensual, costo de configuración).
- Lista completa de características (puntos de viñeta).
- Términos y condiciones (ver más abajo).
- Disponibilidad y elegibilidad.
3. Confirmación de Provisión
Durante la provisión, las características se muestran para que el usuario las revise antes de confirmar:
Características: • 20GB High-Speed Data • Unlimited Calls & Texts • EU Roaming Included • No Contract • 30-Day Expiry
Costo: £15.00/mes Configuración: £0.00
[Cancelar] [Confirmar y Proveer]
4. Detalles del Servicio (Después de la Provisión)
Después de que el servicio esté activo, las características se muestran en la página de detalles del servicio para referencia del cliente.
Formato de Términos y Condiciones:
El campo terms es texto plano que puede incluir saltos de línea:
Dónde Aparecen los Términos en la Interfaz de Usuario:
1. Página de Detalles del Producto
Los términos se muestran en una sección colapsada que se expande al hacer clic:
2. Confirmación de Pedido
Durante la provisión, se requiere una casilla de verificación para que el usuario acepte los términos:
El botón [Provisionar] está deshabilitado hasta que se marque.
3. Facturas
Los términos del servicio pueden incluirse en las facturas como notas al pie para mayor claridad.
Mejores Prácticas:
- Características: Mantener concisas (menos de 50 caracteres cada una), enfocarse en los beneficios clave.
- Términos: Incluir requisitos legales críticos, políticas de expiración, políticas de uso justo.
- Ambos: Actualizar cuando cambie el producto para mantener informados a los clientes.
Paso 8: Vincular el Libro de Jugadas de Provisión de Ansible
{
"provisioning_play": "play_local_mobile_sim",
"provisioning_json_vars": "{
\"days\": 30,
\"data_gb\": 20,
\"voice_minutes\": \"unlimited\",
\"sms_count\": \"unlimited\"
}"
}
provisioning_play- Nombre del libro de jugadas de Ansible (sin extensión .yaml).provisioning_json_vars- Variables predeterminadas pasadas al libro de jugadas.- El libro de jugadas debe existir en:
OmniCRM-API/Provisioners/plays/play_local_mobile_sim.yaml.
Definición Completa del Producto
{
"product_name": "Prepaid Mobile 20GB",
"product_slug": "prepaid-mobile-20gb",
"category": "standalone",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-sim-card",
"comment": "Prepaid mobile SIM with 20GB data, unlimited calls & texts",
"retail_cost": 15.00,
"wholesale_cost": 5.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 1.00,
"contract_days": 30,
"residential": true,
"business": false,
"customer_can_purchase": true,
"available_from": "2025-01-01T00:00:00Z",
"available_until": null,
"auto_renew": "prompt",
"allow_auto_renew": true,
"inventory_items_list": "['SIM Card', 'Mobile Number']",
"features_list": "[
'20GB High-Speed Data',
'Unlimited Calls & Texts',
'EU Roaming Included',
'No Contract',
'30-Day Expiry'
]",
"terms": "Credit expires after 30 days. Data, calls, and texts valid only within expiry period. Fair use policy applies.",
"provisioning_play": "play_local_mobile_sim",
"provisioning_json_vars": "{
\"days\": 30,
\"data_gb\": 20,
\"voice_minutes\": \"unlimited\",
\"sms_count\": \"unlimited\"
}"
}
Creando un Producto Complementario
Los complementos mejoran o modifican servicios existentes. Vienen en dos tipos: complementos virtuales (sin recursos físicos) y complementos de hardware (requieren inventario).
Ejemplo 1: Complemento Virtual (5GB Data Boost)
Un complemento digital que agrega datos a un servicio móvil existente:
{
"product_name": "5GB Data Boost",
"product_slug": "5gb-data-boost",
"category": "addon",
"service_type": "mobile",
"enabled": true,
"icon": "fa-solid fa-plus",
"comment": "Add 5GB extra data to existing mobile service",
"retail_cost": 5.00,
"wholesale_cost": 1.50,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 0.00,
"contract_days": 0,
"residential": true,
"business": true,
"customer_can_purchase": true,
"auto_renew": "false",
"allow_auto_renew": false,
"inventory_items_list": "[]",
"relies_on_list": "",
"features_list": "5GB High-Speed Data. Valid for 7 Days",
"terms": "Data expires after 7 days or when exhausted. Cannot be refunded.",
"provisioning_play": "play_topup_charge_then_action",
"provisioning_json_vars": "{
\"data_gb\": 5,
\"days\": 7
}"
}
Ejemplo 2: Complemento de Hardware (Alquiler de Módem)
Un complemento que proporciona equipo físico para un servicio de fibra existente:
{
"product_name": "WiFi 6 Modem Rental",
"product_slug": "wifi6-modem-rental",
"category": "addon",
"service_type": "internet",
"enabled": true,
"icon": "fa-solid fa-router",
"comment": "Add WiFi 6 modem to fiber service - rental",
"retail_cost": 10.00,
"wholesale_cost": 3.00,
"retail_setup_cost": 0.00,
"wholesale_setup_cost": 45.00,
"contract_days": 30,
"residential": true,
"business": true,
"customer_can_purchase": true,
"auto_renew": "true",
"allow_auto_renew": true,
"inventory_items_list": "['Rental Modem']",
"relies_on_list": "",
"features_list": "WiFi 6 (802.11ax). Dual-band 2.4GHz + 5GHz. Up to 40 devices. Parental controls",
"terms": "Equipment rental. Must be returned on service cancellation or £150 replacement fee applies. Equipment remains property of provider.",
"provisioning_play": "play_addon_assign_modem",
"provisioning_json_vars": "{
\"device_type\": \"modem_router\",
\"requires_configuration\": true
}"
}
Diferencias Clave para Complementos:
category: "addon"- Aplicado a un servicio existente, no independiente.contract_days: 0(virtual) o30(alquiler recurrente) - Frecuencia de facturación.inventory_items_list: "[]"(virtual) o"['Rental Modem']"(hardware) - Recursos físicos.auto_renew: "false"(único) o"true"(alquiler) - Comportamiento recurrente.relies_on_list: ""- Vacío significa que se aplica a cualquier servicio de tiposervice_typecoincidente.
Por qué los Complementos de Hardware Necesitan Inventario:
Los complementos de hardware requieren inventory_items_list porque:
- Rastrear Equipos - Saber qué módem está con qué cliente.
- Prevenir Agotamientos - No se puede provisionar el complemento si no hay módems en stock.
- Recuperación - Cuando el cliente cancela, saber qué equipo recuperar.
- Seguimiento de Costos - Vincular el costo mayorista a un número de serie específico.
- Depreciación - Rastrear el valor del equipo durante el período de alquiler.
- Garantía - Identificar unidades defectuosas por número de serie.
Flujo de Provisión de Complementos con Inventario:
Cuando un cliente añade "Alquiler de Módem WiFi 6" a su servicio de fibra:
- Complemento Seleccionado - El cliente hace clic en "Agregar al Servicio".
- Aparece el Selector de Inventario - Al igual que los servicios independientes:
- Pago Procesado - Se cobra £10.00 de alquiler mensual.
- Módem Asignado - Inventario actualizado:
service_id: Vinculado al servicio de fibra.customer_id: Vinculado al cliente.item_state: "Asignado".
- Envío Activado - El sistema de cumplimiento es notificado para enviar el módem.
- Instalación - El cliente recibe el módem, lo conecta al ONT.
- Facturación Recurrente - Se cobra £10/mes hasta que se cancele el complemento.
Desprovisión de Complementos de Hardware:
Cuando el cliente cancela el alquiler del módem:
- Cancelación Iniciada - El cliente hace clic en "Eliminar Complemento".
- Proceso de Devolución Iniciado:
- Se envía un correo electrónico con instrucciones de devolución.
- Se genera una etiqueta de envío prepagada.
- Período de gracia de 14 días antes de la penalización.
- Equipo Devuelto:
- Inventario actualizado:
item_state= "En Stock" (después de la renovación). - O
item_state= "Dañado" (si es defectuoso). - Vinculado al siguiente cliente una vez renovado.
- Inventario actualizado:
- Sin Devolución:
- Después de 14 días, se cobra una tarifa de reemplazo de £150.
- Inventario marcado:
item_state= "Perdido". - Costo mayorista (£45) + valor de reemplazo recuperado.
Precios para Complementos:
Los complementos pueden tener precios diferentes a los servicios independientes:
- Los complementos virtuales típicamente no tienen costos de configuración.
- Los complementos de hardware pueden tener costos de configuración mayoristas para el equipo.
- Los complementos de alquiler recurrentes utilizan
contract_dayspara la frecuencia de facturación.
Etapa 2: El Proceso de Provisión
Cuando un cliente ordena el producto "Prepaid Mobile 20GB", OmniCRM orquesta la provisión a través de Ansible.
Diagrama de Flujo de Provisión
Cliente Ordena → Selección de Inventario → Trabajo de Provisión Creado ↓ ↓ Pago Autorizado ← Variables Ensambladas ��� Libro de Jugadas de Ansible Ejecutado ↓ ↓ Registro de Servicio Creado → Configuración de Cuenta OCS → Inventario Asignado → Servicio Activo
Flujo de Provisión Paso a Paso
1. El Cliente Inicia el Pedido
Desde la página del cliente:
- El personal hace clic en "Agregar Servicio".
- Selecciona "Prepaid Mobile 20GB" del carrusel de productos.
- Se muestran los detalles del producto y los precios.
2. Selección de Inventario
El sistema solicita el inventario requerido:
- SIM Card - El menú desplegable muestra las SIM disponibles en stock.
- Ejemplo: "SIM-00123 - ICCID: 8944...".
- Mobile Number - El menú desplegable muestra los números de teléfono disponibles.
- Ejemplo: "+44 7700 900123".
El personal o el cliente seleccionan artículos del inventario disponible.
3. Confirmación de Precios
El sistema muestra el precio final:
- Costo de configuración: £0.00 (activación gratuita).
- Costo mensual: £15.00.
- Debido hoy: £15.00 (primer mes).
- Fecha de renovación: 30 días a partir de hoy.
Si se habilita la solicitud de renovación automática, el cliente elige:
- Renovar automáticamente este servicio cada 30 días.
4. Botón de Provisión Habilitado
Cuando se hace clic en "Provisionar", la API:
- Crea un registro de
Provisioncon estado "Ejecutándose" (status=1). - Fusiona variables del producto + solicitud + selecciones de inventario.
- Genera un hilo en segundo plano para ejecutar el libro de jugadas de Ansible.
- Devuelve
provision_ida la interfaz de usuario para seguimiento de estado.
5. Variables Ensambladas
El sistema fusiona variables de múltiples fuentes:
Desde el Producto:
{
"days": 30,
"data_gb": 20,
"voice_minutes": "unlimited",
"sms_count": "unlimited"
}
Desde la Solicitud:
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001,
"Mobile Number": 5002
}
Agregado por el Sistema:
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"initiating_user": 7
}
Variables Finales Pasadas a Ansible:
{
"product_id": 42,
"customer_id": 123,
"SIM Card": 5001,
"Mobile Number": 5002,
"days": 30,
"data_gb": 20,
"voice_minutes": "unlimited",
"sms_count": "unlimited",
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"initiating_user": 7
}
6. Ejecución del Libro de Jugadas de Ansible
El libro de jugadas play_local_mobile_sim.yaml se ejecuta con estas variables.
Comprendiendo el Libro de Jugadas de Provisión de Ansible
Examinemos un libro de jugadas de provisión real para entender lo que sucede detrás de escena.
Ejemplo de Libro de Jugadas de Provisión de SIM Móvil
Ubicación:
OmniCRM-API/Provisioners/plays/play_local_mobile_sim.yaml
Estructura de Alto Nivel:
- name: Mobile SIM Provisioning
hosts: localhost
gather_facts: no
become: False
tasks:
- name: Main block
block:
# 1. Load configuration
# 2. Fetch product details from API
# 3. Fetch customer details from API
# 4. Fetch inventory details from API
# 5. Create account in OCS (CGRateS)
# 6. Add balances and allowances to OCS
# 7. Create service record in CRM
# 8. Assign inventory to service
# 9. Record transactions
# 10. Send welcome notifications
rescue:
# Rollback on failure
# - Remove OCS account
# - Release inventory
# - Log error
Recorrido Detallado del Libro de Jugadas:
Tarea 1: Cargar Configuración
- name: Include vars of crm_config
ansible.builtin.include_vars:
file: "../../crm_config.yaml"
name: crm_config
Carga la configuración del sistema incluyendo:
- URL y credenciales de OCS/CGRateS.
- URL base de CRM.
- Configuración de inquilino.
Tarea 2: Obtener Detalles del Producto
- name: Get Product information from CRM API
uri:
url: "{{ crm_config.crm.base_url }}/crm/product/product_id/{{ product_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
return_content: yes
register: api_response_product
Qué Hace Esto:
- Llama a
GET /crm/product/product_id/42. - Recupera la definición completa del producto.
- Almacena en la variable
api_response_product.
Por qué: Aunque tenemos provisioning_json_vars del producto, recuperamos el producto completo para obtener:
- Precios más recientes (pueden haber cambiado desde que comenzó el pedido).
- Nombre del producto para el nombramiento del servicio.
- Lista de características para documentación.
- Costos mayoristas para seguimiento de márgenes.
Tarea 3: Establecer Hechos del Paquete
- name: Set package facts
set_fact:
package_name: "{{ api_response_product.json.product_name }}"
monthly_cost: "{{ api_response_product.json.retail_cost }}"
setup_cost: "{{ api_response_product.json.retail_setup_cost }}"
Extrae valores comúnmente utilizados en variables simples para mejorar la legibilidad.
Tarea 4: Obtener Detalles del Inventario
- name: Get SIM information from CRM API
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_sim
- name: Set IMSI from Inventory response
set_fact:
imsi: "{{ api_response_sim.json.itemtext2 }}"
iccid: "{{ api_response_sim.json.itemtext1 }}"
Qué Hace Esto:
- Busca el ID de inventario de la tarjeta SIM 5001.
- Recupera los detalles de la SIM:
itemtext1= ICCID (número de tarjeta SIM).itemtext2= IMSI (identidad del suscriptor).
- Hace lo mismo para el número de teléfono móvil (recupera el número de teléfono).
Por qué Esto Importa:
- IMSI es necesario para provisionar al suscriptor en el HSS (Servidor de Suscriptores Local).
- ICCID se registra en las notas del servicio para resolución de problemas.
- El número de teléfono (MSISDN) se muestra al cliente y se utiliza para el enrutamiento.
Tarea 5: Generar UUID del Servicio
- name: Generate UUID Fact
set_fact:
uuid: "{{ 99999999 | random | to_uuid }}"
- name: Set Service UUID
set_fact:
service_uuid: "Local_Mobile_SIM_{{ uuid[0:8] }}"
Qué Hace Esto:
- Genera un UUID aleatorio.
- Crea un service_uuid como
Local_Mobile_SIM_a3f2c1d8.
Por qué:
- El UUID del servicio es el identificador único en OCS/CGRateS.
- Se utiliza para todas las operaciones de carga.
- Debe ser globalmente único entre todos los servicios.
Tarea 6: Crear Cuenta en OCS
- name: Create account in OCS
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
headers:
Content-Type: "application/json"
body:
{
"method": "ApierV2.SetAccount",
"params": [{
"Tenant": "{{ crm_config.ocs.ocsTenant }}",
"Account": "{{ service_uuid }}",
"ActionPlanIds": [],
"ExtraOptions": {
"AllowNegative": false,
"Disabled": false
},
"ReloadScheduler": true
}]
}
register: ocs_create_response
Qué Hace Esto:
- Llama a la API JSON-RPC de CGRateS.
- Crea una nueva cuenta con service_uuid.
- Establece la cuenta como activa (no deshabilitada).
- Previene saldo negativo (modo prepago).
Por qué:
- La cuenta de OCS es donde ocurre toda la carga.
- Los saldos (datos, voz, SMS, dinero) se almacenan aquí.
- El uso se rastrea y califica en tiempo real.
Tarea 7: Agregar Saldo de Datos
- name: Add 20GB Data Balance
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Tenant": "{{ crm_config.ocs.ocsTenant }}",
"Account": "{{ service_uuid }}",
"BalanceType": "*data",
"Balance": {
"ID": "DATA_20GB_Monthly",
"Value": 21474836480,
"ExpiryTime": "+720h",
"Weight": 10,
"DestinationIDs": "*any"
}
}]
}
Qué Hace Esto:
- Agrega 20GB de saldo de datos a la cuenta.
- Valor: 21474836480 bytes (20 * 1024 * 1024 * 1024).
- Expira en 720 horas (30 días).
- Peso 10 (peso más alto consumido primero).
Tarea 8: Agregar Voz y SMS Ilimitados
- name: Add Unlimited Voice
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Account": "{{ service_uuid }}",
"BalanceType": "*voice",
"Balance": {
"ID": "VOICE_Unlimited",
"Value": 999999999,
"ExpiryTime": "+720h"
}
}]
}
- Agrega 999,999,999 segundos de voz (esencialmente ilimitado).
- Expira en 30 días.
Tarea 9: Crear Registro de Servicio en CRM
- name: Add Service via API
uri:
url: "{{ crm_config.crm.base_url }}/crm/service/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"product_id": "{{ product_id }}",
"service_name": "Mobile - {{ phone_number }}",
"service_type": "mobile",
"service_uuid": "{{ service_uuid }}",
"service_status": "Active",
"service_provisioned_date": "{{ provision_datetime }}",
"retail_cost": "{{ monthly_cost }}",
"wholesale_cost": "{{ api_response_product.json.wholesale_cost }}",
"icon": "fa-solid fa-sim-card"
}
register: service_creation_response
Qué Crea Esto:
- Registro de servicio vinculado al cliente.
- Vincula a OCS a través de
service_uuid. - Almacena costos minoristas y mayoristas.
- Establece el estado como "Activo".
- Devuelve
service_idpara operaciones posteriores.
Tarea 10: Asignar Inventario al Servicio
- name: Assign SIM Card to Service
uri:
url: "{{ crm_config.crm.base_url }}/crm/inventory/inventory_id/{{ hostvars[inventory_hostname]['SIM Card'] }}"
method: PATCH
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"service_id": "{{ service_creation_response.json.service_id }}",
"customer_id": "{{ customer_id }}",
"item_state": "Assigned"
}
Qué Hace Esto:
- Actualiza el registro de inventario de la tarjeta SIM.
- Establece
service_idpara vincular la SIM al servicio. - Cambia el estado de "En Stock" a "Asignado".
- Repite para el inventario del número de teléfono móvil.
Por qué:
- Rastrear qué SIM está asignada a qué cliente.
- Prevenir la doble asignación de inventario.
- Habilitar informes y auditorías de inventario.
Tarea 11: Registrar Transacción de Costo de Configuración
- name: Add Setup Cost Transaction
uri:
url: "{{ crm_config.crm.base_url }}/crm/transaction/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_creation_response.json.service_id }}",
"title": "{{ package_name }} - Setup",
"description": "Activation fee",
"retail_cost": "{{ setup_cost }}",
"wholesale_cost": "{{ api_response_product.json.wholesale_setup_cost }}"
}
Qué Hace Esto:
- Registra un cargo de configuración de £0.00 al cliente (minorista).
- Registra un costo mayorista de £1.00.
- Crea un registro de transacción para la facturación.
Tarea 12: Bloque de Rescate (Manejo de Errores)
rescue:
- name: Remove account in OCS on failure
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.RemoveAccount",
"params": [{
"Account": "{{ service_uuid }}"
}]
}
- name: Fail the provisioning
fail:
msg: "Provisioning failed, rolled back OCS account"
Qué Hace Esto:
- Si alguna tarea falla, se ejecuta el bloque de rescate.
- Elimina la cuenta de OCS que fue parcialmente creada.
- Libera el inventario de nuevo a "En Stock".
- Falla el trabajo de provisión con un mensaje de error.
Por qué:
- Previene cuentas huérfanas en OCS.
- Asegura un rollback limpio en errores.
- Mantiene la consistencia de datos.
Provisión Completa: Qué Se Creó
Después de una provisión exitosa, el sistema tiene:
1. Cuenta OCS (CGRateS):
- ID de cuenta:
Local_Mobile_SIM_a3f2c1d8. - Saldos:
- 20GB de datos (expira en 30 días).
- Voz ilimitada (999M segundos, expira en 30 días).
- SMS ilimitados (999M mensajes, expira en 30 días).
2. Registro de Servicio en CRM:
- ID de servicio: 1234.
- Cliente: John Doe (customer_id: 123).
- Producto: Prepaid Mobile 20GB (product_id: 42).
- Nombre del servicio: "Mobile - +44 7700 900123".
- UUID del servicio:
Local_Mobile_SIM_a3f2c1d8. - Estado: Activo.
- Costo mensual: £15.00 (minorista), £5.00 (mayorista).
- Beneficio: £10.00/mes.
3. Asignaciones de Inventario:
- SIM Card 5001: Asignada al servicio 1234, cliente 123.
- Mobile Number 5002: Asignado al servicio 1234, cliente 123.
4. Registros de Transacción:
- Se creó una transacción de costo de configuración.
- Se registró el cargo del primer mes.
5. El Cliente Ahora Puede:
- Ver el servicio en el portal de autoservicio.
- Ver el saldo de datos de 20GB.
- Hacer llamadas y enviar SMS.
- Recargar o agregar complementos.
- Ver el uso en tiempo real.
Etapa 3: Agregar Complementos y Recargas
Después de que un servicio esté activo, los clientes pueden comprar complementos para mejorar su servicio.
Flujo de Provisión de Complementos
Supongamos que el cliente ha utilizado 18GB de su asignación de 20GB y desea comprar el complemento "5GB Data Boost".
1. El Cliente Navega al Servicio
- Abre la página "Mobile - +44 7700 900123".
- Ve el uso actual: 18GB de 20GB utilizados (90%).
- Hace clic en "Agregar Complemento" o "Recargar".
2. El Sistema Filtra los Complementos Disponibles
Solo muestra complementos donde:
category = "addon".service_type = "mobile"(coincide con el tipo de servicio).residential = true(si el cliente es residencial).enabled = true.
El cliente ve: "5GB Data Boost - £5.00".
3. El Cliente Selecciona el Complemento
- Hace clic en "5GB Data Boost".
- Confirma la compra por £5.00.
- El sistema captura la autorización del pago.
4. Se Inicia la Provisión del Complemento
El sistema llama a play_topup_charge_then_action.yaml con variables:
{
"product_id": 43, # Producto 5GB Data Boost
"customer_id": 123,
"service_id": 1234, # Servicio existente
"access_token": "eyJ...",
"data_gb": 5, # Desde provisioning_json_vars
"days": 7 # Desde provisioning_json_vars
}
Diferencia Clave con Respecto a Servicios Independientes:
service_idestá incluido (servicio existente a modificar).- No se requiere inventario.
- No se crea un servicio (modifica el existente).
Recorrido del Libro de Jugadas de Provisión de Complementos
Tarea 1: Obtener Detalles del Servicio
- name: Get Service information from CRM API
uri:
url: "http://localhost:5000/crm/service/service_id/{{ service_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_service
- name: Set service facts
set_fact:
service_uuid: "{{ api_response_service.json.service_uuid }}"
customer_id: "{{ api_response_service.json.customer_id }}"
Por qué:
- Necesitamos
service_uuidpara agregar saldo a la cuenta de OCS correcta. - Verifica que el servicio exista y esté activo.
- Asegura que el servicio pertenezca al cliente.
Tarea 2: Cobrar al Cliente
- name: Get Customer's Default Payment Method
uri:
url: "http://localhost:5000/crm/stripe/customer_id/{{ customer_id }}"
method: GET
headers:
Authorization: "Bearer {{ access_token }}"
register: api_response_stripe
- name: Get default card ID
set_fact:
customer_stripe_id: "{{ api_response_stripe.json | json_query(query) }}"
vars:
query: "data[?default_payment_method==`true`].customer_stripe_id | [0]"
- name: Charge card
uri:
url: "http://localhost:5000/crm/stripe/charge_card/{{ customer_stripe_id }}"
method: POST
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"retail_cost": 5.00,
"description": "5GB Data Boost",
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_id }}",
"product_id": "{{ product_id }}",
"wholesale_cost": 1.50,
"invoice": true
}
register: charge_response
- name: Assert payment successful
assert:
that:
- charge_response.status == 200
Qué Hace Esto:
- Encuentra el método de pago predeterminado del cliente en Stripe.
- Cobra £5.00 a la tarjeta.
- Registra el costo mayorista de £1.50 para seguimiento de márgenes.
- Crea una transacción vinculada al servicio.
- Agrega a la próxima factura.
- Falla la provisión si el pago falla.
Por qué Cobrar Primero:
- No se entrega crédito hasta que se confirme el pago.
- Previene fraudes.
- Coincide el pago con la provisión del complemento.
Tarea 3: Agregar Saldo de Datos a OCS
- name: Add 5GB Data Balance
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body_format: json
body:
{
"method": "ApierV1.AddBalance",
"params": [{
"Account": "{{ service_uuid }}",
"BalanceType": "*data",
"Balance": {
"ID": "DATA_5GB_Boost_{{ uuid }}",
"Value": 5368709120,
"ExpiryTime": "+168h",
"Weight": 20
}
}]
}
Qué Hace Esto:
- Agrega 5GB (5368709120 bytes) a la cuenta.
- Expira en 168 horas (7 días).
- Peso 20 (peso más alto consumido primero - impulso antes de la asignación mensual).
Saldo del Cliente Después del Complemento:
- Mensual original: 2GB restantes (expira en 25 días).
- Nuevo impulso: 5GB (expira en 7 días).
- Total disponible: 7GB.
- Orden de uso: impulso consumido primero, luego mensual.
Tarea 4: Registrar Transacción
- name: Add Addon Transaction
uri:
url: "http://localhost:5000/crm/transaction/"
method: PUT
body_format: json
headers:
Authorization: "Bearer {{ access_token }}"
body:
{
"customer_id": "{{ customer_id }}",
"service_id": "{{ service_id }}",
"title": "5GB Data Boost",
"description": "Additional 5GB data valid for 7 days",
"retail_cost": 5.00,
"wholesale_cost": 1.50
}
Qué Hace Esto:
- Registra un cargo de £5.00 al cliente.
- Registra un costo mayorista de £1.50.
- Vincula la transacción al servicio para informes.
Resumen Completo del Flujo de Complementos
- El cliente selecciona el complemento de la lista filtrada.
- Pago autorizado y cobrado.
- Saldo de datos agregado a la cuenta de OCS.
- Transacción registrada en CRM.
- El cliente ve inmediatamente el saldo actualizado: 7GB disponibles.
Seguimiento Financiero:
- Cargo mensual del servicio: £15 minorista, £5 mayorista.
- Compra de complemento: £5 minorista, £1.50 mayorista.
Renovación Automática: Complementos Recurrentes
Algunos complementos pueden configurarse para renovarse automáticamente (planes de datos mensuales, suscripciones, etc.).
Configuración del Producto:
{
"product_name": "Monthly 10GB Data Plan",
"category": "addon",
"retail_cost": 10.00,
"contract_days": 30,
"auto_renew": "true",
"provisioning_play": "play_topup_charge_then_action"
}
La Provisión Crea un Plan de Acción:
- name: Create ActionPlan for Auto-Renewal
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV1.SetActionPlan",
"params": [{
"Id": "ServiceID_{{ service_uuid }}__ProductID_{{ product_id }}__MonthlyRenewal",
"ActionPlan": [{
"ActionsId": "Action_{{ product_slug }}",
"Years": "*any",
"Months": "*any",
"MonthDays": "*any",
"WeekDays": "*any",
"Time": "00:00:00",
"Weight": 10
}],
"Overwrite": false,
"ReloadScheduler": true
}]
}
Qué Hace Esto:
- Crea una tarea programada en OCS.
- Ejecuta
Action_{{ product_slug }}cada 30 días. - La acción cobra al cliente y vuelve a aplicar el saldo de datos.
- Continúa hasta que el cliente cancele.
Gestión del Cliente:
- El cliente ve "Próxima Renovación: 1 de febrero de 2025 - £10.00" en la vista del servicio.
- Puede hacer clic en "Cancelar Renovación Automática" para detener futuros cargos.
- Puede hacer clic en "Renovar Ahora" para aplicar inmediatamente la asignación del próximo mes.
Etapa 4: Desprovisión de Servicios
Cuando un cliente cancela el servicio, el sistema debe eliminar limpiamente todos los recursos.
Disparadores de Desprovisión
La desprovisión puede ser desencadenada por:
- Cancelación del cliente - El cliente hace clic en "Cancelar Servicio".
- Acción administrativa - El personal marca el servicio para desactivación.
- No pago - El servicio expira debido a falta de renovación.
- Fin del contrato - El contrato a plazo fijo llega a su fecha de finalización.
Flujo de Desprovisión
1. El Cliente Inicia la Cancelación
- Navega al servicio.
- Hace clic en "Cancelar Servicio".
- El sistema solicita: "¿Está seguro? Cualquier saldo restante se perderá."
- El cliente confirma.
2. Período de Gracia (Opcional)
Algunos operadores implementan un período de gracia:
- Servicio marcado como "Cancelación Pendiente".
- Permanece activo durante 7-30 días.
- El cliente puede revertir la cancelación durante el período de gracia.
- Desprovisión automática después del período de gracia.
3. Trabajo de Desprovisión Creado
El sistema crea un trabajo de provisión con:
{
"action": "deprovision",
"service_id": 1234,
"customer_id": 123,
"service_uuid": "Local_Mobile_SIM_a3f2c1d8"
}
Llama al libro de jugadas especificado en service.deprovisioning_play o al bloque de rescate del libro de jugadas original.
4. Libro de Jugadas de Desprovisión de Ansible
- name: Deprovision Mobile Service
hosts: localhost
tasks:
- name: Disable OCS Account
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.SetAccount",
"params": [{
"Account": "{{ service_uuid }}",
"ExtraOptions": { "Disabled": true }
}]
}
- name: Remove ActionPlans (stop auto-renewals)
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV1.RemoveActionPlan",
"params": [{
"Id": "ServiceID_{{ service_uuid }}__*"
}]
}
- name: Update Service Status in CRM
uri:
url: "http://localhost:5000/crm/service/{{ service_id }}"
method: PATCH
body:
{
"service_status": "Deactivated",
"service_deactivate_date": "{{ current_datetime }}"
}
- name: Release Inventory to Stock
uri:
url: "http://localhost:5000/crm/inventory/inventory_id/{{ sim_card_id }}"
method: PATCH
body:
{
"service_id": null,
"customer_id": null,
"item_state": "Decommissioned"
}
Qué Hace Esto:
- Desactiva la cuenta de OCS - Detiene toda la carga, se bloquea el uso.
- Elimina ActionPlans - Cancela las renovaciones automáticas.
- Actualiza el servicio en CRM - Estado "Desactivado", fecha registrada.
- Libera el inventario - SIM marcada como "Desmantelada", disponible para reutilización (después de renovación).
5. Post-Desprovisión
El sistema realiza limpieza:
- El cliente ya no ve el servicio en el portal de autoservicio.
- El servicio permanece en CRM para informes históricos.
- Las transacciones y facturas se preservan para contabilidad.
- El inventario puede ser renovado y reutilizado.
- La cuenta de OCS puede ser archivada después del período de retención.
Desprovisión Parcial vs Completa
Desprovisión Parcial (Suspensión):
- Usado para no pago o suspensión temporal.
- Cuenta de OCS desactivada pero no eliminada.
- Saldos preservados.
- Puede ser reactivada cuando se reciba el pago.
- name: Suspend Service
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.SetAccount",
"params": [{
"Account": "{{ service_uuid }}",
"ExtraOptions": { "Disabled": true }
}]
}
Desprovisión Completa (Cancelación Permanente):
- Usado para cancelación permanente.
- Cuenta de OCS eliminada por completo.
- Saldos perdidos.
- No puede ser reactivada.
- name: Remove OCS Account
uri:
url: "http://{{ crm_config.ocs.cgrates }}/jsonrpc"
method: POST
body:
{
"method": "ApierV2.RemoveAccount",
"params": [{
"Account": "{{ service_uuid }}"
}]
}
Mejores Prácticas para la Gestión de Productos
Gestión del Ciclo de Vida del Producto
Estados del Producto:
enabled: true- Producto disponible para nuevos pedidos.enabled: false- Producto deshabilitado, los servicios existentes continúan.
Deshabilitando Productos:
- Marque el producto como
enabled: falsepara prevenir nuevos pedidos. - Los servicios existentes permanecen activos.
- Los clientes aún pueden renovar/modificar servicios existentes.
- Útil para descontinuar productos antiguos.
Gestión de Inventario
Estados del Inventario:
New- Stock nuevo, listo para asignar.In Stock- Disponible para provisión.Assigned- Vinculado al servicio del cliente.Decommissioned- Puede ser renovado y reutilizado.Damaged- Necesita reparación o eliminación.
Reutilizando Inventario:
Después de la desprovisión:
- Tarjetas SIM: Renovar y marcar como "En Stock".
- Números de teléfono: Liberar después del período de portabilidad (30 días).
- Equipos: Probar, renovar, marcar como "Usado".
Métricas de Provisión
Monitorear:
- Tasa de éxito de provisión.
- Tiempo promedio de provisión.
- Puntos de fallo comunes.
- Rotación de inventario.