216 lines
9.3 KiB
Python
216 lines
9.3 KiB
Python
"""
|
|
Seed de tickets de demostración para ServiceManagerWeb.
|
|
Crea tickets variados con categorías, sistemas y prioridades diferentes.
|
|
"""
|
|
import asyncio
|
|
import sys
|
|
|
|
sys.path.insert(0, '/app')
|
|
|
|
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession
|
|
from sqlalchemy.orm import sessionmaker
|
|
from sqlalchemy import select
|
|
|
|
from app.core.config import get_settings
|
|
from app.models.tenant import Tenant
|
|
from app.models.user import User
|
|
from app.models.category import Category
|
|
from app.models.system import System
|
|
from app.models.ticket import Ticket, TicketStatus, TicketPriority
|
|
from app.models.comment import TicketComment
|
|
|
|
settings = get_settings()
|
|
|
|
TENANT_SLUG = "aduanasoft-demo"
|
|
|
|
DEMO_TICKETS = [
|
|
{
|
|
"subject": "Error en módulo de importaciones del ERP",
|
|
"description": "Al intentar registrar una nueva importación, el sistema arroja el error 'NullReferenceException' en el módulo de gestión aduanera. Esto bloquea completamente el flujo de trabajo de importaciones para todos los usuarios del área.",
|
|
"priority": TicketPriority.URGENT,
|
|
"category_name": "Incidentes Críticos",
|
|
"system_name": "ERP Aduanero",
|
|
"status": TicketStatus.IN_PROGRESS,
|
|
},
|
|
{
|
|
"subject": "No puedo acceder al portal web desde el lunes",
|
|
"description": "Desde el lunes 18 de febrero, el portal web no carga correctamente. La página queda en blanco y en la consola del navegador aparece un error 503. He probado desde diferentes equipos y navegadores con el mismo resultado.",
|
|
"priority": TicketPriority.HIGH,
|
|
"category_name": "Soporte Técnico",
|
|
"system_name": "Portal Web",
|
|
"status": TicketStatus.NEW,
|
|
},
|
|
{
|
|
"subject": "Solicitud de capacitación en módulo de reportes",
|
|
"description": "Nuestro equipo necesita una sesión de capacitación para el nuevo módulo de reportes y BI. Somos 8 personas del área de contabilidad. Por favor confirmar disponibilidad para la semana del 3 de marzo.",
|
|
"priority": TicketPriority.LOW,
|
|
"category_name": "Capacitación",
|
|
"system_name": "Reportes y BI",
|
|
"status": TicketStatus.NEW,
|
|
},
|
|
{
|
|
"subject": "Discrepancia en factura #F-2024-0892",
|
|
"description": "La factura F-2024-0892 emitida el 15 de febrero muestra un monto de $47,500 MXN pero según nuestros registros el importe correcto es $45,200 MXN. Favor revisar y emitir nota de crédito si corresponde.",
|
|
"priority": TicketPriority.MEDIUM,
|
|
"category_name": "Facturación",
|
|
"system_name": None,
|
|
"status": TicketStatus.WAITING_CUSTOMER,
|
|
},
|
|
{
|
|
"subject": "La app móvil no sincroniza pedidos pendientes",
|
|
"description": "En la aplicación móvil versión 3.2.1, los pedidos creados desde el celular no se sincronizan al ERP. Ya desinstalé y reinstalé la app. El problema persiste en iOS y Android.",
|
|
"priority": TicketPriority.HIGH,
|
|
"category_name": "Soporte Técnico",
|
|
"system_name": "App Móvil",
|
|
"status": TicketStatus.IN_PROGRESS,
|
|
},
|
|
{
|
|
"subject": "Consulta sobre proceso de pedimento de exportación",
|
|
"description": "¿Cuáles son los documentos necesarios para tramitar un pedimento de exportación bajo la clave A1? Necesito la lista actualizada con los cambios del SAT de enero 2025.",
|
|
"priority": TicketPriority.LOW,
|
|
"category_name": "Consultas Generales",
|
|
"system_name": None,
|
|
"status": TicketStatus.RESOLVED,
|
|
},
|
|
{
|
|
"subject": "Servidores lentos en horario pico (11am-2pm)",
|
|
"description": "Durante el horario de 11am a 2pm el ERP se vuelve extremadamente lento. Las consultas que normalmente tardan 2 segundos pueden llevar hasta 45 segundos. El problema afecta a todos los usuarios concurrentemente.",
|
|
"priority": TicketPriority.URGENT,
|
|
"category_name": "Infraestructura",
|
|
"system_name": "ERP Aduanero",
|
|
"status": TicketStatus.IN_PROGRESS,
|
|
},
|
|
{
|
|
"subject": "Error al generar reporte mensual de exportaciones",
|
|
"description": "El reporte de exportaciones del mes de enero no se genera correctamente. Al dar clic en 'Generar PDF' aparece un error: 'Timeout al procesar el reporte'. Necesito este reporte para la reunión del viernes.",
|
|
"priority": TicketPriority.MEDIUM,
|
|
"category_name": "Soporte Técnico",
|
|
"system_name": "Reportes y BI",
|
|
"status": TicketStatus.NEW,
|
|
},
|
|
]
|
|
|
|
DEMO_COMMENTS = {
|
|
"Error en módulo de importaciones del ERP": [
|
|
("admin@aduanasoft.com", "Hemos identificado el problema. Es un error en la versión 4.2.1 del ERP. Estamos aplicando el parche de emergencia. Estimamos resolución en 2 horas.", False),
|
|
("cliente@empresa-demo.com", "Gracias por la respuesta rápida. ¿Podemos continuar con el registro manual mientras tanto?", False),
|
|
],
|
|
"No puedo acceder al portal web desde el lunes": [
|
|
("agente@aduanasoft.com", "Hemos recibido tu ticket. ¿Puedes indicarnos el mensaje exacto que aparece en la consola del navegador? Esto nos ayudará a diagnosticar más rápido.", False),
|
|
],
|
|
}
|
|
|
|
|
|
async def main():
|
|
engine = create_async_engine(settings.DATABASE_URL, echo=False)
|
|
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
|
|
|
|
async with async_session() as session:
|
|
# Obtener tenant
|
|
result = await session.execute(select(Tenant).where(Tenant.slug == TENANT_SLUG))
|
|
tenant = result.scalar_one_or_none()
|
|
if not tenant:
|
|
print(f"ERROR: Tenant '{TENANT_SLUG}' no encontrado.")
|
|
return
|
|
|
|
tenant_id = tenant.id
|
|
print(f"✅ Tenant: {tenant.name}")
|
|
|
|
# Obtener usuario cliente para asignar como creador
|
|
client_user_result = await session.execute(
|
|
select(User).where(User.email == "cliente@empresa-demo.com").limit(1)
|
|
)
|
|
client_user = client_user_result.scalar_one_or_none()
|
|
if not client_user:
|
|
print("ERROR: cliente@empresa-demo.com no encontrado")
|
|
return
|
|
|
|
# Obtener agente para comentarios
|
|
agent_result = await session.execute(
|
|
select(User).where(User.email == "agente@aduanasoft.com").limit(1)
|
|
)
|
|
agent_user = agent_result.scalar_one_or_none()
|
|
|
|
admin_result = await session.execute(
|
|
select(User).where(User.email == "admin@aduanasoft.com").limit(1)
|
|
)
|
|
admin_user = admin_result.scalar_one_or_none()
|
|
|
|
# Mapear categorías y sistemas
|
|
cats_result = await session.execute(select(Category).where(Category.tenant_id == tenant_id))
|
|
cats = {c.name: c for c in cats_result.scalars().all()}
|
|
|
|
sys_result = await session.execute(select(System).where(System.tenant_id == tenant_id))
|
|
systems = {s.name: s for s in sys_result.scalars().all()}
|
|
|
|
# Verificar tickets existentes
|
|
existing_tickets_result = await session.execute(
|
|
select(Ticket).where(Ticket.tenant_id == tenant_id)
|
|
)
|
|
existing_subjects = {t.subject for t in existing_tickets_result.scalars().all()}
|
|
|
|
print(f"\n🎫 Creando tickets de demostración:")
|
|
created = 0
|
|
ticket_objects = {}
|
|
|
|
for ticket_data in DEMO_TICKETS:
|
|
subject = ticket_data["subject"]
|
|
if subject in existing_subjects:
|
|
print(f" ⏭ Ya existe: {subject[:50]}...")
|
|
continue
|
|
|
|
cat_name = ticket_data.pop("category_name", None)
|
|
sys_name = ticket_data.pop("system_name", None)
|
|
|
|
category = cats.get(cat_name) if cat_name else None
|
|
system = systems.get(sys_name) if sys_name else None
|
|
|
|
ticket = Ticket(
|
|
tenant_id=tenant_id,
|
|
category_id=category.id if category else None,
|
|
affected_system_id=system.id if system else None,
|
|
created_by=client_user.id,
|
|
**ticket_data,
|
|
)
|
|
session.add(ticket)
|
|
await session.flush() # Para obtener el ID
|
|
ticket_objects[subject] = ticket
|
|
print(f" ✓ [{ticket_data['priority'].value}] {subject[:60]}")
|
|
created += 1
|
|
|
|
await session.flush()
|
|
|
|
# Crear comentarios de demostración
|
|
print(f"\n💬 Añadiendo comentarios:")
|
|
for subject, comments in DEMO_COMMENTS.items():
|
|
ticket = ticket_objects.get(subject)
|
|
if not ticket:
|
|
continue
|
|
for author_email, content, is_internal in comments:
|
|
if author_email == "admin@aduanasoft.com":
|
|
author = admin_user
|
|
elif author_email == "agente@aduanasoft.com":
|
|
author = agent_user
|
|
else:
|
|
author = client_user
|
|
|
|
if author:
|
|
comment = TicketComment(
|
|
ticket_id=ticket.id,
|
|
author_id=author.id,
|
|
content=content,
|
|
is_internal=is_internal,
|
|
)
|
|
session.add(comment)
|
|
print(f" ✓ Comentario en '{subject[:40]}...' por {author_email}")
|
|
|
|
await session.commit()
|
|
print(f"\n✅ {created} tickets creados exitosamente.")
|
|
|
|
await engine.dispose()
|
|
print("🎉 Seed de tickets completado.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|