docs: Actualizar README con documentacion completa
Documentacion completa incluyendo: - Arquitectura del proyecto con estructura de carpetas - Instalacion con Docker y manual - Variables de entorno completas (Mattermost, NocoDB, OCR, Reportes) - Uso del dashboard web y PWA - Todos los comandos de Mattermost - API endpoints completos (Dashboard, Analytics, Reportes, OCR) - Sistema de comisiones y bonos por racha - OCR: formatos soportados, preprocesamiento adaptativo, patrones - Analytics: algoritmo de prediccion, metricas, comparativas - Reportes PDF: diario y ejecutivo - Estructura de codigo y dependencias - Troubleshooting comun Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,186 +1,501 @@
|
||||
# Sales Bot - Aplicación Principal
|
||||
# Sales Bot
|
||||
|
||||
Bot de automatización de ventas para Mattermost con procesamiento OCR de tickets.
|
||||
Sistema de automatizacion de ventas para Mattermost con procesamiento OCR, analytics avanzados, reportes PDF y PWA.
|
||||
|
||||
## Caracteristicas
|
||||
|
||||
- **Bot de Mattermost**: Registro de ventas via chat con confirmacion
|
||||
- **OCR Inteligente**: Extraccion automatica de datos de tickets con preprocesamiento adaptativo
|
||||
- **Dashboard PWA**: Aplicacion web instalable con soporte offline
|
||||
- **Analytics**: Graficas interactivas, predicciones y comparativas
|
||||
- **Reportes PDF**: Generacion automatica de reportes diarios y ejecutivos
|
||||
- **Sistema de Comisiones**: Calculo automatico con bonos por racha
|
||||
- **Notificaciones Programadas**: Recordatorios y resumenes automaticos
|
||||
|
||||
## Arquitectura
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Sales Bot │
|
||||
├─────────────────────────────────────────────────────────────────┤
|
||||
│ │
|
||||
│ ┌─────────────┐ ┌──────────────┐ ┌──────────────────┐ │
|
||||
│ │ Flask │ │ WebSocket │ │ OCR Processor │ │
|
||||
│ │ (app.py) │ │ Listener │ │ │ │
|
||||
│ └──────┬──────┘ └──────┬───────┘ └────────┬─────────┘ │
|
||||
│ │ │ │ │
|
||||
│ └──────────────────┼──────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌───────┴───────┐ │
|
||||
│ │ Handlers │ │
|
||||
│ │ (handlers.py) │ │
|
||||
│ └───────┬───────┘ │
|
||||
│ │ │
|
||||
│ ┌──────────────────┼──────────────────┐ │
|
||||
│ │ │ │ │
|
||||
│ ┌──────┴──────┐ ┌─────┴──────┐ ┌─────┴──────┐ │
|
||||
│ │ Mattermost │ │ NocoDB │ │ Utils │ │
|
||||
│ │ Client │ │ Client │ │ │ │
|
||||
│ └─────────────┘ └────────────┘ └────────────┘ │
|
||||
│ │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
sales-bot/
|
||||
├── app.py # Aplicacion Flask principal
|
||||
├── handlers.py # Manejadores de eventos de ventas
|
||||
├── mattermost_client.py # Cliente API Mattermost
|
||||
├── nocodb_client.py # Cliente API NocoDB
|
||||
├── websocket_listener.py # Listener tiempo real
|
||||
├── scheduler.py # Tareas programadas
|
||||
├── utils.py # Utilidades
|
||||
├── export_utils.py # Exportacion Excel/CSV
|
||||
│
|
||||
├── analytics/ # Modulo de analytics
|
||||
│ ├── __init__.py
|
||||
│ ├── predictions.py # Predicciones ML (promedio movil + regresion)
|
||||
│ ├── trends.py # Analisis de tendencias
|
||||
│ └── comparisons.py # Comparativas temporales
|
||||
│
|
||||
├── reports/ # Modulo de reportes PDF
|
||||
│ ├── __init__.py
|
||||
│ └── pdf_generator.py # Generador con ReportLab
|
||||
│
|
||||
├── ocr/ # Modulo OCR mejorado
|
||||
│ ├── __init__.py
|
||||
│ ├── processor.py # Procesador principal
|
||||
│ ├── preprocessor.py # Preprocesamiento adaptativo
|
||||
│ ├── patterns.py # Patrones de tickets
|
||||
│ └── amount_detector.py # Detector de montos
|
||||
│
|
||||
├── templates/ # Templates HTML
|
||||
│ ├── base.html # Template base con navbar
|
||||
│ ├── dashboard.html # Dashboard principal
|
||||
│ ├── analytics.html # Dashboard analytics
|
||||
│ └── executive.html # Dashboard ejecutivo
|
||||
│
|
||||
├── static/ # Archivos estaticos
|
||||
│ ├── css/main.css # Estilos principales
|
||||
│ ├── js/
|
||||
│ │ ├── app.js # Logica principal
|
||||
│ │ ├── charts.js # Integracion Chart.js
|
||||
│ │ ├── camera.js # Captura de camara
|
||||
│ │ └── pwa.js # Service Worker
|
||||
│ ├── manifest.json # Manifest PWA
|
||||
│ └── service-worker.js # Cache offline
|
||||
│
|
||||
├── compose.yaml # Docker Compose
|
||||
├── Dockerfile # Imagen Docker
|
||||
├── requirements.txt # Dependencias Python
|
||||
└── .env.example # Variables de entorno ejemplo
|
||||
```
|
||||
|
||||
## Módulos
|
||||
## Instalacion
|
||||
|
||||
### app.py
|
||||
Aplicación Flask principal con los siguientes endpoints:
|
||||
|
||||
- `GET /health` - Health check
|
||||
- `POST /webhook/mattermost` - Recibe webhooks de Mattermost
|
||||
- `POST /webhook/nocodb` - Recibe webhooks de NocoDB
|
||||
- `POST /comando/metas` - Comando slash /metas
|
||||
- `POST /comando/ranking` - Comando slash /ranking
|
||||
|
||||
### handlers.py
|
||||
Manejadores de eventos de ventas:
|
||||
|
||||
- `handle_venta_message()` - Procesa mensajes de venta
|
||||
- `generar_reporte_diario()` - Genera reportes diarios
|
||||
|
||||
### mattermost_client.py
|
||||
Cliente para la API de Mattermost:
|
||||
|
||||
```python
|
||||
client = MattermostClient(url, token)
|
||||
client.test_connection()
|
||||
client.post_message(channel_id, message)
|
||||
client.add_reaction(post_id, emoji)
|
||||
client.get_file(file_id)
|
||||
```
|
||||
|
||||
### nocodb_client.py
|
||||
Cliente para la API de NocoDB:
|
||||
|
||||
```python
|
||||
client = NocoDBClient(url, token)
|
||||
client.crear_vendedor(username, nombre, email)
|
||||
client.registrar_venta(vendedor, monto, cliente, imagen)
|
||||
client.get_ventas_dia(vendedor, fecha)
|
||||
client.get_ranking_vendedores(mes)
|
||||
```
|
||||
|
||||
### ocr_processor.py
|
||||
Procesador OCR para tickets:
|
||||
|
||||
```python
|
||||
processor = OCRProcessor()
|
||||
resultado = processor.procesar_imagen(imagen_bytes)
|
||||
# Retorna: monto, fecha, productos, tubos_detectados
|
||||
```
|
||||
|
||||
### websocket_listener.py
|
||||
Listener para eventos en tiempo real de Mattermost:
|
||||
|
||||
```python
|
||||
listener = MattermostWebsocketListener(url, token, callback)
|
||||
listener.start() # Inicia en thread separado
|
||||
```
|
||||
|
||||
### utils.py
|
||||
Funciones de utilidad:
|
||||
|
||||
```python
|
||||
extraer_monto(texto) # "@monto 1500" → 1500.0
|
||||
extraer_cliente(texto) # "@cliente Juan" → "Juan"
|
||||
extraer_tubos(texto) # "@tubos 5" → 5
|
||||
formatear_moneda(1500) # → "$1,500.00"
|
||||
```
|
||||
|
||||
## Instalación con Docker
|
||||
### Con Docker (Recomendado)
|
||||
|
||||
```bash
|
||||
# Clonar repositorio
|
||||
git clone https://git.consultoria-as.com/consultoria-as/sales-bot-stacks.git
|
||||
cd sales-bot-stacks/sales-bot
|
||||
|
||||
# Configurar variables de entorno
|
||||
cp .env.example .env
|
||||
nano .env # Editar con tus credenciales
|
||||
|
||||
# Construir e iniciar
|
||||
docker compose build
|
||||
docker compose up -d
|
||||
|
||||
# Verificar
|
||||
curl http://localhost:5000/health
|
||||
```
|
||||
|
||||
## Instalación Manual
|
||||
### Instalacion Manual
|
||||
|
||||
```bash
|
||||
# Instalar Tesseract
|
||||
apt-get install tesseract-ocr tesseract-ocr-eng tesseract-ocr-spa
|
||||
# Instalar Tesseract OCR
|
||||
apt-get update
|
||||
apt-get install -y tesseract-ocr tesseract-ocr-spa tesseract-ocr-eng
|
||||
|
||||
# Instalar dependencias Python
|
||||
pip install -r requirements.txt
|
||||
|
||||
# Configurar variables
|
||||
cp .env.example .env
|
||||
nano .env
|
||||
|
||||
# Ejecutar
|
||||
python app.py
|
||||
```
|
||||
|
||||
## Variables de Entorno
|
||||
## Configuracion
|
||||
|
||||
| Variable | Descripción | Ejemplo |
|
||||
### Variables de Entorno
|
||||
|
||||
| Variable | Descripcion | Ejemplo |
|
||||
|----------|-------------|---------|
|
||||
| MATTERMOST_URL | URL de Mattermost | http://192.168.10.204:8065 |
|
||||
| MATTERMOST_BOT_TOKEN | Token del bot | xxx |
|
||||
| MATTERMOST_TEAM_NAME | Nombre del team | sales |
|
||||
| MATTERMOST_WEBHOOK_SECRET | Secret del webhook | xxx |
|
||||
| NOCODB_URL | URL de NocoDB | http://192.168.10.204:8080 |
|
||||
| NOCODB_TOKEN | Token de API | xxx |
|
||||
| NOCODB_TABLE_* | IDs de tablas | xxx |
|
||||
| FLASK_PORT | Puerto de Flask | 5000 |
|
||||
| LOG_LEVEL | Nivel de logging | INFO |
|
||||
| TZ_OFFSET | Offset de zona horaria | -6 |
|
||||
| **Mattermost** | | |
|
||||
| `MATTERMOST_URL` | URL de Mattermost | `http://192.168.10.204:8065` |
|
||||
| `MATTERMOST_BOT_TOKEN` | Token del bot | `abc123...` |
|
||||
| `MATTERMOST_TEAM_NAME` | Nombre del equipo | `sales` |
|
||||
| `MATTERMOST_WEBHOOK_SECRET` | Secret del webhook | `xyz789...` |
|
||||
| **NocoDB** | | |
|
||||
| `NOCODB_URL` | URL de NocoDB | `http://192.168.10.204:8080` |
|
||||
| `NOCODB_TOKEN` | Token de API | `abc123...` |
|
||||
| `NOCODB_TABLE_VENDEDORES` | ID tabla vendedores | `tbl_xxx` |
|
||||
| `NOCODB_TABLE_VENTAS` | ID tabla ventas | `tbl_xxx` |
|
||||
| `NOCODB_TABLE_VENTAS_DETALLE` | ID tabla detalles | `tbl_xxx` |
|
||||
| `NOCODB_TABLE_METAS` | ID tabla metas | `tbl_xxx` |
|
||||
| **Flask** | | |
|
||||
| `FLASK_PORT` | Puerto del servidor | `5000` |
|
||||
| `FLASK_DEBUG` | Modo debug | `False` |
|
||||
| **Scheduler** | | |
|
||||
| `SCHEDULER_ENABLED` | Habilitar tareas | `True` |
|
||||
| `RECORDATORIO_MEDIODIA_HORA` | Hora recordatorio | `12` |
|
||||
| `RESUMEN_DIARIO_HORA` | Hora resumen diario | `18` |
|
||||
| **Comisiones** | | |
|
||||
| `META_DIARIA_TUBOS_DEFAULT` | Meta diaria tubos | `3` |
|
||||
| `COMISION_POR_TUBO_DEFAULT` | Comision por tubo | `10` |
|
||||
| `BONUS_3_DIAS` | Bonus 3 dias racha | `20` |
|
||||
| `BONUS_5_DIAS` | Bonus 5 dias racha | `50` |
|
||||
| `BONUS_10_DIAS` | Bonus 10 dias racha | `150` |
|
||||
| **OCR** | | |
|
||||
| `OCR_ENABLE_DESKEW` | Correccion rotacion | `true` |
|
||||
| `OCR_MAX_ROTATION_ANGLE` | Angulo max rotacion | `15` |
|
||||
| `OCR_CONFIDENCE_THRESHOLD` | Umbral confianza | `0.6` |
|
||||
| `OCR_USE_ADAPTIVE_PIPELINE` | Pipeline adaptativo | `true` |
|
||||
| **Reportes** | | |
|
||||
| `REPORTS_OUTPUT_DIR` | Directorio reportes | `/app/reports` |
|
||||
| `SCHEDULED_PDF_REPORT_ENABLED` | PDF automatico | `true` |
|
||||
| `SCHEDULED_PDF_REPORT_HOUR` | Hora PDF diario | `18` |
|
||||
|
||||
## Formato de Mensajes de Venta
|
||||
## Uso
|
||||
|
||||
El bot reconoce varios formatos:
|
||||
### Dashboard Web
|
||||
|
||||
Accede al dashboard en: `http://tu-servidor:5000/dashboard`
|
||||
|
||||
**Funcionalidades del Dashboard:**
|
||||
- KPIs en tiempo real (ventas hoy/mes, vendedores activos)
|
||||
- Grafica de tendencias (7/14/30 dias) con predicciones
|
||||
- Comparativas semanales y mensuales
|
||||
- Ranking de vendedores con tubos y comisiones
|
||||
- Tabla de Top Performers con % de meta
|
||||
- Generacion de reportes PDF
|
||||
- Captura de tickets desde camara (mobile)
|
||||
|
||||
**PWA (Progressive Web App):**
|
||||
- Instalable en celular desde Chrome/Safari
|
||||
- Funciona offline con datos cacheados
|
||||
- Notificaciones push (futuro)
|
||||
|
||||
### Comandos de Mattermost
|
||||
|
||||
**Comandos Basicos:**
|
||||
```
|
||||
/metas - Ver tu progreso del mes
|
||||
/ranking - Ver ranking de vendedores
|
||||
/ayuda - Mostrar ayuda completa
|
||||
```
|
||||
|
||||
**Comandos de Gestion:**
|
||||
```
|
||||
/cancelar <id> [motivo] - Cancelar una venta
|
||||
/editar <id> @monto X @cliente Y - Editar una venta
|
||||
/deshacer - Deshacer ultima venta (5 min)
|
||||
```
|
||||
|
||||
**Comandos de Comisiones:**
|
||||
```
|
||||
/comisiones - Ver historial de comisiones
|
||||
/racha - Ver racha actual y bonos
|
||||
/exportar [csv] [mes] - Exportar ventas a Excel/CSV
|
||||
```
|
||||
|
||||
**Comandos de Reportes:**
|
||||
```
|
||||
/reporte diario - Generar PDF del dia
|
||||
/reporte semanal - Generar PDF de la semana
|
||||
/reporte ejecutivo - Generar PDF ejecutivo
|
||||
```
|
||||
|
||||
### Registro de Ventas
|
||||
|
||||
**Formatos Soportados:**
|
||||
```
|
||||
# Formato con @
|
||||
venta @monto 1500 @cliente Juan @tubos 5
|
||||
venta @monto 1500 @cliente Juan Perez @tubos 5
|
||||
|
||||
# Formato con etiquetas
|
||||
venta monto: 1500 cliente: Juan
|
||||
|
||||
# Formato natural
|
||||
venta $1,500 a Juan
|
||||
venta $1,500 a Juan Perez
|
||||
|
||||
# Con foto de ticket (OCR automatico)
|
||||
[Adjuntar imagen del ticket]
|
||||
```
|
||||
|
||||
## Procesamiento OCR
|
||||
**Flujo de Confirmacion:**
|
||||
1. Envias mensaje de venta o foto de ticket
|
||||
2. El bot muestra preview con datos extraidos
|
||||
3. Respondes **si** para confirmar o **no** para cancelar
|
||||
4. Timeout de 2 minutos si no respondes
|
||||
|
||||
El procesador OCR detecta automáticamente:
|
||||
- Monto total
|
||||
- Fecha del ticket
|
||||
- Lista de productos
|
||||
- Cantidad de tubos de tinte
|
||||
## API Endpoints
|
||||
|
||||
### Dashboard
|
||||
| Metodo | Endpoint | Descripcion |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/dashboard` | Dashboard principal |
|
||||
| GET | `/dashboard/analytics` | Dashboard analytics |
|
||||
| GET | `/dashboard/executive` | Dashboard ejecutivo |
|
||||
|
||||
### API Dashboard
|
||||
| Metodo | Endpoint | Descripcion |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/api/dashboard/resumen` | KPIs del dia y mes |
|
||||
| GET | `/api/dashboard/ranking` | Ranking vendedores |
|
||||
| GET | `/api/dashboard/ventas-recientes` | Ultimas ventas |
|
||||
| GET | `/api/dashboard/metas` | Estado de metas |
|
||||
|
||||
### API Analytics
|
||||
| Metodo | Endpoint | Params | Descripcion |
|
||||
|--------|----------|--------|-------------|
|
||||
| GET | `/api/analytics/trends` | `days`, `vendedor` | Tendencias de ventas |
|
||||
| GET | `/api/analytics/predictions` | `days`, `predict` | Predicciones ML |
|
||||
| GET | `/api/analytics/comparisons` | `type` (weekly/monthly/yearly) | Comparativas |
|
||||
| GET | `/api/analytics/performance/<username>` | - | Rendimiento vendedor |
|
||||
|
||||
### API Reportes
|
||||
| Metodo | Endpoint | Body | Descripcion |
|
||||
|--------|----------|------|-------------|
|
||||
| POST | `/api/reports/generate` | `{type, vendedor}` | Generar PDF |
|
||||
| GET | `/api/reports/download/<id>` | - | Descargar PDF |
|
||||
|
||||
### API OCR
|
||||
| Metodo | Endpoint | Body | Descripcion |
|
||||
|--------|----------|------|-------------|
|
||||
| POST | `/api/capture/ticket` | `{image, user_name}` | Procesar ticket base64 |
|
||||
|
||||
### Webhooks
|
||||
| Metodo | Endpoint | Descripcion |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/webhook/mattermost` | Webhook saliente Mattermost |
|
||||
| POST | `/webhook/nocodb` | Webhook NocoDB |
|
||||
|
||||
### Comandos Slash
|
||||
| Metodo | Endpoint | Descripcion |
|
||||
|--------|----------|-------------|
|
||||
| POST | `/comando/metas` | Comando /metas |
|
||||
| POST | `/comando/ranking` | Comando /ranking |
|
||||
| POST | `/comando/ayuda` | Comando /ayuda |
|
||||
| POST | `/comando/cancelar` | Comando /cancelar |
|
||||
| POST | `/comando/editar` | Comando /editar |
|
||||
| POST | `/comando/deshacer` | Comando /deshacer |
|
||||
| POST | `/comando/comisiones` | Comando /comisiones |
|
||||
| POST | `/comando/racha` | Comando /racha |
|
||||
| POST | `/comando/exportar` | Comando /exportar |
|
||||
| POST | `/comando/reporte` | Comando /reporte |
|
||||
|
||||
### Utilidades
|
||||
| Metodo | Endpoint | Descripcion |
|
||||
|--------|----------|-------------|
|
||||
| GET | `/health` | Health check |
|
||||
| GET | `/manifest.json` | PWA manifest |
|
||||
| GET | `/service-worker.js` | Service worker |
|
||||
| POST | `/reporte/diario` | Generar reporte manual |
|
||||
| GET | `/test/mattermost` | Test conexion Mattermost |
|
||||
| GET | `/test/nocodb` | Test conexion NocoDB |
|
||||
|
||||
## Sistema de Comisiones
|
||||
|
||||
### Calculo de Comisiones
|
||||
```
|
||||
Meta diaria: 3 tubos
|
||||
Comision: $10 por tubo despues de meta
|
||||
|
||||
Ejemplo:
|
||||
- Vendiste 7 tubos
|
||||
- Tubos comisionables: 7 - 3 = 4
|
||||
- Comision: 4 x $10 = $40
|
||||
```
|
||||
|
||||
### Bonos por Racha
|
||||
| Dias Consecutivos | Bonus |
|
||||
|-------------------|-------|
|
||||
| 3 dias | $20 |
|
||||
| 5 dias | $50 |
|
||||
| 10 dias | $150 |
|
||||
|
||||
### Niveles de Racha
|
||||
- **CONSTRUYENDO**: 0-2 dias
|
||||
- **RACHA ACTIVA**: 3-4 dias
|
||||
- **EN FUEGO**: 5-9 dias
|
||||
- **LEGENDARIO**: 10+ dias
|
||||
|
||||
## OCR - Procesamiento de Tickets
|
||||
|
||||
### Formatos Soportados
|
||||
- OXXO
|
||||
- Walmart / Bodega Aurrera
|
||||
- Soriana
|
||||
- 7-Eleven
|
||||
- Farmacias (Guadalajara, Similares, etc.)
|
||||
- Tiendas de pintura/tinte (Cromatique, etc.)
|
||||
- Tickets genericos
|
||||
|
||||
### Preprocesamiento Adaptativo
|
||||
El sistema detecta automaticamente la mejor configuracion:
|
||||
- **Standard**: Tickets con buena iluminacion
|
||||
- **Low Contrast**: Tickets deslavados
|
||||
- **Noisy**: Tickets con ruido/manchas
|
||||
- **Rotated**: Tickets inclinados (hasta 15 grados)
|
||||
- **Dark**: Tickets oscuros
|
||||
- **Light**: Tickets sobreexpuestos
|
||||
|
||||
### Patrones de Monto Detectados
|
||||
1. `TOTAL A PAGAR: $X,XXX.XX`
|
||||
2. `GRAN TOTAL: $X,XXX.XX`
|
||||
3. `TOTAL: $X,XXX.XX`
|
||||
4. `IMPORTE: $X,XXX.XX`
|
||||
5. `A COBRAR: $X,XXX.XX`
|
||||
6. `SUMA: $X,XXX.XX`
|
||||
7. `SUBTOTAL: $X,XXX.XX`
|
||||
|
||||
### Marcas de Tinte Reconocidas
|
||||
- Alfaparf Evolution
|
||||
- Wella Koleston
|
||||
- Loreal
|
||||
- Matrix
|
||||
- Schwarzkopf
|
||||
- Loreal Majirel
|
||||
- Matrix SoColor
|
||||
- Schwarzkopf Igora
|
||||
- Revlon
|
||||
- Igora
|
||||
- Majirel
|
||||
- Cromatique
|
||||
|
||||
## Sistema de Comisiones
|
||||
## Analytics y Predicciones
|
||||
|
||||
### Algoritmo de Prediccion
|
||||
Combina dos metodos:
|
||||
1. **Promedio Movil**: Ultimos 7 dias
|
||||
2. **Regresion Lineal**: Tendencia historica
|
||||
|
||||
```python
|
||||
META_DIARIA_TUBOS = 3
|
||||
COMISION_POR_TUBO = 10 # $10 MXN
|
||||
|
||||
def calcular_comision(tubos_vendidos):
|
||||
if tubos_vendidos > META_DIARIA_TUBOS:
|
||||
return (tubos_vendidos - META_DIARIA_TUBOS) * COMISION_POR_TUBO
|
||||
return 0
|
||||
prediccion = (promedio_movil + prediccion_lineal) / 2
|
||||
```
|
||||
|
||||
## Logs
|
||||
### Metricas Disponibles
|
||||
- **Tendencia**: Increasing / Stable / Decreasing
|
||||
- **Confianza**: 0-100% (basado en R-squared)
|
||||
- **Predicciones**: Siguiente dia, 3 dias, semana
|
||||
|
||||
Los logs se escriben en `/app/logs/sales-bot.log` con formato:
|
||||
### Comparativas
|
||||
- **Semanal**: Esta semana vs anterior
|
||||
- **Mensual**: Este mes vs anterior (3 meses)
|
||||
- **Anual**: YTD actual vs YTD anterior
|
||||
|
||||
## Reportes PDF
|
||||
|
||||
### Reporte Diario
|
||||
- Resumen de KPIs del dia
|
||||
- Grafica de tendencias
|
||||
- Top 5 vendedores
|
||||
- Detalle de ventas
|
||||
|
||||
### Reporte Ejecutivo
|
||||
- KPIs del mes
|
||||
- Comparativas mensuales
|
||||
- Ranking completo
|
||||
- Graficas de rendimiento
|
||||
- Proyecciones
|
||||
|
||||
## Desarrollo
|
||||
|
||||
### Estructura de Codigo
|
||||
|
||||
**app.py** - Aplicacion principal
|
||||
```python
|
||||
app = Flask(__name__)
|
||||
|
||||
# Rutas del dashboard
|
||||
@app.route('/dashboard')
|
||||
@app.route('/dashboard/analytics')
|
||||
@app.route('/dashboard/executive')
|
||||
|
||||
# API endpoints
|
||||
@app.route('/api/dashboard/...')
|
||||
@app.route('/api/analytics/...')
|
||||
@app.route('/api/reports/...')
|
||||
|
||||
# Comandos slash
|
||||
@app.route('/comando/...')
|
||||
```
|
||||
2024-01-15 10:30:45 INFO [app] Venta registrada: $1,500.00 - Juan - vendedor1
|
||||
|
||||
**analytics/predictions.py** - Predicciones
|
||||
```python
|
||||
def prediccion_basica(ventas_diarias, dias_prediccion=7):
|
||||
# Promedio movil + regresion lineal
|
||||
return {
|
||||
'predicciones': [...],
|
||||
'tendencia': 'increasing|stable|decreasing',
|
||||
'confidence': 0.85
|
||||
}
|
||||
```
|
||||
|
||||
**ocr/processor.py** - OCR
|
||||
```python
|
||||
processor = OCRProcessor()
|
||||
result = processor.process(image_bytes)
|
||||
# result: {texto, monto, cliente, fecha, tubos, formato, confianza}
|
||||
```
|
||||
|
||||
**reports/pdf_generator.py** - PDFs
|
||||
```python
|
||||
pdf = SalesReportPDF(ventas, stats)
|
||||
content = pdf.generar_reporte_diario()
|
||||
# content: bytes del PDF
|
||||
```
|
||||
|
||||
### Dependencias Principales
|
||||
|
||||
```txt
|
||||
# Web Framework
|
||||
Flask==3.0.0
|
||||
gunicorn==21.2.0
|
||||
|
||||
# OCR
|
||||
pytesseract==0.3.10
|
||||
Pillow==10.2.0
|
||||
opencv-python==4.9.0.80
|
||||
|
||||
# PDF
|
||||
reportlab==4.1.0
|
||||
matplotlib==3.8.2
|
||||
|
||||
# Analytics
|
||||
scipy==1.12.0
|
||||
pandas==2.1.4
|
||||
numpy==1.26.3
|
||||
|
||||
# OCR Mejorado
|
||||
imutils==0.5.4
|
||||
deskew==1.1.0
|
||||
|
||||
# Mattermost
|
||||
mattermostdriver==7.3.2
|
||||
|
||||
# Scheduler
|
||||
APScheduler==3.10.4
|
||||
|
||||
# Excel
|
||||
openpyxl==3.1.2
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### El dashboard no carga
|
||||
```bash
|
||||
# Verificar que el contenedor esta corriendo
|
||||
docker ps | grep sales-bot
|
||||
|
||||
# Ver logs
|
||||
docker logs sales-bot --tail 100
|
||||
|
||||
# Reconstruir imagen
|
||||
docker compose build --no-cache
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
### OCR no detecta el monto
|
||||
- Verificar que la imagen tenga buena iluminacion
|
||||
- Probar con imagen de mayor resolucion
|
||||
- El ticket no debe estar muy inclinado (max 15 grados)
|
||||
|
||||
### Predicciones muestran 0
|
||||
- Se requieren al menos 3 dias de datos historicos
|
||||
- Verificar que hay ventas registradas
|
||||
|
||||
### PDF no se genera
|
||||
```bash
|
||||
# Verificar que reportlab esta instalado
|
||||
docker exec sales-bot pip list | grep reportlab
|
||||
|
||||
# Si no esta, reconstruir imagen
|
||||
docker compose build --no-cache
|
||||
```
|
||||
|
||||
## Health Check
|
||||
@@ -193,7 +508,15 @@ Respuesta:
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"timestamp": "2024-01-15T10:30:45",
|
||||
"timestamp": "2026-01-19T10:30:45",
|
||||
"version": "1.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
## Licencia
|
||||
|
||||
Proyecto privado - Consultoria AS
|
||||
|
||||
## Contacto
|
||||
|
||||
Para soporte tecnico contactar al equipo de desarrollo.
|
||||
|
||||
Reference in New Issue
Block a user