Mejoras integrales: visitas, POS, WACRM, reportes, temas y módulos legacy
- Módulo Visitas completo (auto desde agenda, insumos con descargo de inventario, fotos antes/después y documentos, receta imprimible) - Punto de Venta (catálogo + ticket sticky, cobro con cambio, pago con puntos monedero, ticket imprimible) - WACRM: leads automáticos desde WhatsApp, asignación de conversaciones y leads a agentes, conversión lead→paciente, ficha del paciente en chat - Pacientes: completitud de expediente, alertas clínicas, historial unificado con detalle, foto, WhatsApp, estado de cuenta, filtros rápidos (VIP/recientes/médico), documentos (expediente escaneado + galería) - Agenda: vistas por médico y por hora, filtros rápidos (libres, primera vez, check-in, no-show), modal de acciones, bloqueos por médico, drag&drop para mover citas - Reportes: 18 pestañas (diario, cortes, ingresos, inventario, adeudos, comisiones, pagos, devoluciones, top clientes, horas, paquetes, vendedores, concentrado, recomendaciones, KPIs) con exportación Excel - Temas: nuevo tema Clásico (look legacy AdminLTE) con submenús tipo treeview, selector de tema; accesos rápidos personalizables con 3 presentaciones; búsqueda global; notificaciones reales - Configuración: secciones (clínica, usuarios con permisos por sección, recetas, catálogos de diagnósticos y procedimientos) - Inventario: alertas de caducidad y sugerencia de compra, cron diario que descuenta artículos caducados, compras/bajas - Consultas Médicas, página Expedientes, importadores delta (citas/visitas legacy idempotentes), depuración de duplicados - Infra: tema Tailwind conectado (@config), gzip en nginx, secuencias Odoo corregidas (noupdate, company_id), rollback en validaciones
This commit is contained in:
@@ -5,7 +5,7 @@ import Layout from '../components/Layout';
|
||||
import { Card, PageHeader, Button, toast } from '../components/ui';
|
||||
import { odooApi } from '../services/odoo';
|
||||
import type { Birthday } from '../services/odoo';
|
||||
import { downloadCsv } from '../lib/utils';
|
||||
import { exportToExcel } from '../lib/exporter';
|
||||
|
||||
type Period = 'today' | 'week' | 'month';
|
||||
|
||||
@@ -50,18 +50,35 @@ const Cumpleanos: FC = () => {
|
||||
};
|
||||
}, [period]);
|
||||
|
||||
const exportBirthdays = () => {
|
||||
const rows: (string | number | boolean | null | undefined)[][] = [
|
||||
['Nombre', 'Teléfono', 'Fecha nacimiento', 'Cumple el', 'Cumple años', 'Última visita', 'Total gastado', 'Adeudo', 'VIP'],
|
||||
];
|
||||
items.forEach((b) =>
|
||||
rows.push([
|
||||
b.name, b.phone, b.birth_date, b.occurs_on, b.turning_age, b.last_visit,
|
||||
b.total_spent, b.amount_due, b.is_vip ? 'Sí' : 'No',
|
||||
])
|
||||
);
|
||||
downloadCsv(`cumpleaneros-skeen-${period}-${new Date().toISOString().split('T')[0]}.csv`, rows);
|
||||
toast.success(`CSV descargado (${items.length} cumpleañeros)`);
|
||||
const exportBirthdays = async () => {
|
||||
try {
|
||||
await exportToExcel({
|
||||
filename: `cumpleaneros-skeen-${period}-${new Date().toISOString().split('T')[0]}`,
|
||||
sheetName: 'Cumpleañeros',
|
||||
title: 'Cumpleañeros SKEEN',
|
||||
subtitle: `Periodo: ${period} · ${items.length} pacientes`,
|
||||
columns: [
|
||||
{ header: 'Nombre', key: 'name' },
|
||||
{ header: 'Teléfono', key: 'phone' },
|
||||
{ header: 'Fecha nacimiento', key: 'birth_date', format: 'date' },
|
||||
{ header: 'Cumple el', key: 'occurs_on', format: 'date' },
|
||||
{ header: 'Cumple años', key: 'turning_age', format: 'number' },
|
||||
{ header: 'Última visita', key: 'last_visit', format: 'date' },
|
||||
{ header: 'Total gastado', key: 'total_spent', format: 'currency' },
|
||||
{ header: 'Adeudo', key: 'amount_due', format: 'currency' },
|
||||
{ header: 'VIP', key: 'vip' },
|
||||
],
|
||||
rows: items.map((b) => ({
|
||||
name: b.name, phone: b.phone, birth_date: b.birth_date, occurs_on: b.occurs_on,
|
||||
turning_age: b.turning_age, last_visit: b.last_visit, total_spent: b.total_spent,
|
||||
amount_due: b.amount_due, vip: b.is_vip ? 'Sí' : 'No',
|
||||
})),
|
||||
});
|
||||
toast.success(`Excel descargado (${items.length} cumpleañeros)`);
|
||||
} catch (err) {
|
||||
toast.error('Error al exportar');
|
||||
console.error(err);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user