import { produtoService } from './produtoService'; import { pedidoService } from './pedidoService'; import { empresaService } from './empresaService'; export interface DashboardStats { medicamentosDisponiveis: number; medicamentosVencimento: number; pedidosRecebidos: number; pedidosPendentes: number; vendasMes: number; crescimentoVendas: number; // Porcentagem economiaGerada: number; } export interface AtividadeRecente { id: string; tipo: 'pedido' | 'produto' | 'usuario'; titulo: string; descricao: string; data: string; status: 'novo' | 'atualizado' | 'pendente' | 'concluido'; } export interface PedidoPendente { id: string; numero: string; status: string; valor: number; comprador: string; data: string; } // Tipo para representar documentos do banco interface Documento { $id: string; $createdAt: string; $updatedAt: string; [key: string]: any; } class DashboardService { /** * Obtém estatísticas do dashboard baseadas no nível do usuário */ async obterEstatisticas(userRole: string, empresaId?: string): Promise { try { console.log(`📊 [DashboardService] Obtendo estatísticas para role: ${userRole}, empresa: ${empresaId}`); let stats: DashboardStats = { medicamentosDisponiveis: 0, medicamentosVencimento: 0, pedidosRecebidos: 0, pedidosPendentes: 0, vendasMes: 0, crescimentoVendas: 0, economiaGerada: 0, }; if (userRole?.toLowerCase() === 'admin') { // Admin ve dados globais stats = await this.obterEstatisticasGlobais(); } else if (userRole?.toLowerCase() === 'owner' && empresaId) { // Owner ve dados da propria empresa stats = await this.obterEstatisticasEmpresa(empresaId); } else if (userRole?.toLowerCase() === 'employee' && empresaId) { // Employee ve dados limitados da empresa stats = await this.obterEstatisticasColaborador(empresaId); } console.log(`✅ [DashboardService] Estatísticas obtidas:`, stats); return stats; } catch (error) { console.error('❌ [DashboardService] Erro ao obter estatísticas:', error); throw error; } } /** * Estatísticas globais para Super Admin */ private async obterEstatisticasGlobais(): Promise { try { // Obter produtos de todas as empresas const produtosResponse = await produtoService.listar(); const produtos = produtosResponse.documents || []; // Obter pedidos de todas as empresas const pedidosResponse = await pedidoService.listar(); const pedidos = pedidosResponse.documents || []; // Calcular medicamentos próximos ao vencimento (próximos 30 dias) const dataLimite = new Date(); dataLimite.setDate(dataLimite.getDate() + 30); const medicamentosVencimento = produtos.filter((produto: Documento) => { if (produto['data-vencimento']) { const dataVencimento = new Date(produto['data-vencimento']); return dataVencimento <= dataLimite; } return false; }).length; // Calcular pedidos pendentes const pedidosPendentes = pedidos.filter((pedido: Documento) => ['pendente', 'aguardando_aprovacao'].includes(pedido.status?.toLowerCase()) ).length; // Calcular vendas do mês atual const inicioMes = new Date(); inicioMes.setDate(1); inicioMes.setHours(0, 0, 0, 0); const vendasMes = pedidos.filter((pedido: Documento) => { const dataPedido = new Date(pedido.$createdAt); return dataPedido >= inicioMes && pedido.status === 'concluido'; }).length; // Calcular economia gerada (valor total dos produtos vendidos) const economiaGerada = pedidos .filter((pedido: Documento) => pedido.status === 'concluido') .reduce((total: number, pedido: Documento) => total + (pedido['valor-total'] || 0), 0); return { medicamentosDisponiveis: produtos.length, medicamentosVencimento, pedidosRecebidos: pedidos.length, pedidosPendentes, vendasMes, crescimentoVendas: 25, // Calcular baseado no mês anterior economiaGerada, }; } catch (error) { console.error('❌ [DashboardService] Erro nas estatísticas globais:', error); throw error; } } /** * Estatísticas da empresa para Admin */ private async obterEstatisticasEmpresa(empresaId: string): Promise { try { // Obter produtos da empresa const produtosResponse = await produtoService.listarPorEmpresa(empresaId); const produtos = produtosResponse.documents || []; // Obter pedidos da empresa (vendas e compras) const pedidosResponse = await pedidoService.listar(); const todosPedidos = pedidosResponse.documents || []; // Filtrar pedidos relacionados à empresa const pedidos = todosPedidos.filter((pedido: Documento) => pedido.vendedor?.includes(empresaId) || pedido.comprador === empresaId ); // Calcular medicamentos próximos ao vencimento const dataLimite = new Date(); dataLimite.setDate(dataLimite.getDate() + 30); const medicamentosVencimento = produtos.filter((produto: Documento) => { if (produto['data-vencimento']) { const dataVencimento = new Date(produto['data-vencimento']); return dataVencimento <= dataLimite; } return false; }).length; // Filtrar pedidos recebidos (onde a empresa é vendedora) const pedidosRecebidos = pedidos.filter((pedido: Documento) => pedido.vendedor && pedido.vendedor.includes(empresaId) ); const pedidosPendentes = pedidosRecebidos.filter((pedido: Documento) => ['pendente', 'aguardando_aprovacao'].includes(pedido.status?.toLowerCase()) ).length; // Calcular vendas do mês const inicioMes = new Date(); inicioMes.setDate(1); inicioMes.setHours(0, 0, 0, 0); const vendasMes = pedidosRecebidos.filter((pedido: Documento) => { const dataPedido = new Date(pedido.$createdAt); return dataPedido >= inicioMes && pedido.status === 'concluido'; }).length; // Calcular economia gerada pela empresa const economiaGerada = pedidosRecebidos .filter((pedido: Documento) => pedido.status === 'concluido') .reduce((total: number, pedido: Documento) => total + (pedido['valor-total'] || 0), 0); return { medicamentosDisponiveis: produtos.length, medicamentosVencimento, pedidosRecebidos: pedidosRecebidos.length, pedidosPendentes, vendasMes, crescimentoVendas: 15, // Calcular baseado no mês anterior economiaGerada, }; } catch (error) { console.error('❌ [DashboardService] Erro nas estatísticas da empresa:', error); throw error; } } /** * Estatísticas limitadas para Colaborador */ private async obterEstatisticasColaborador(empresaId: string): Promise { try { // Colaboradores veem apenas estatísticas básicas da empresa const produtosResponse = await produtoService.listarPorEmpresa(empresaId); const produtos = produtosResponse.documents || []; // Medicamentos próximos ao vencimento const dataLimite = new Date(); dataLimite.setDate(dataLimite.getDate() + 30); const medicamentosVencimento = produtos.filter((produto: Documento) => { if (produto['data-vencimento']) { const dataVencimento = new Date(produto['data-vencimento']); return dataVencimento <= dataLimite; } return false; }).length; return { medicamentosDisponiveis: produtos.length, medicamentosVencimento, pedidosRecebidos: 0, // Colaboradores não veem pedidos pedidosPendentes: 0, vendasMes: 0, crescimentoVendas: 0, economiaGerada: 0, }; } catch (error) { console.error('❌ [DashboardService] Erro nas estatísticas do colaborador:', error); throw error; } } /** * Obtém atividades recentes */ async obterAtividadesRecentes(userRole: string, empresaId?: string, limit: number = 5): Promise { try { console.log(`📋 [DashboardService] Obtendo atividades recentes para role: ${userRole}`); const atividades: AtividadeRecente[] = []; // Obter pedidos recentes const normalizedRole = userRole?.toLowerCase() const pedidosResponse = normalizedRole === 'admin' ? await pedidoService.listar(1, limit) : await pedidoService.listar(1, limit); const todosPedidos = pedidosResponse.documents || []; // Filtrar pedidos da empresa se não for SUPERADMIN const pedidos = normalizedRole === 'admin' ? todosPedidos : todosPedidos.filter((pedido: any) => pedido.vendedor?.includes(empresaId!) || pedido.comprador === empresaId! ); // Converter pedidos em atividades pedidos.forEach((pedido: Documento) => { atividades.push({ id: pedido.$id, tipo: 'pedido', titulo: `Novo pedido recebido`, descricao: `Pedido #${pedido.$id.substring(0, 8)} - R$ ${(pedido['valor-total'] || 0).toFixed(2)}`, data: pedido.$createdAt, status: pedido.status === 'pendente' ? 'novo' : 'atualizado', }); }); // Obter produtos recentemente atualizados const produtosResponse = normalizedRole === 'admin' ? await produtoService.listar(1, limit) : await produtoService.listarPorEmpresa(empresaId!, 1, limit); const produtos = produtosResponse.documents || []; // Converter produtos em atividades produtos.slice(0, 2).forEach((produto: Documento) => { atividades.push({ id: produto.$id, tipo: 'produto', titulo: `Produto atualizado`, descricao: produto.nome || `Produto ${produto.$id.substring(0, 8)}`, data: produto.$updatedAt, status: 'atualizado', }); }); // Ordenar por data mais recente atividades.sort((a, b) => new Date(b.data).getTime() - new Date(a.data).getTime()); return atividades.slice(0, limit); } catch (error) { console.error('❌ [DashboardService] Erro ao obter atividades recentes:', error); return []; } } /** * Obtém pedidos pendentes */ async obterPedidosPendentes(userRole: string, empresaId?: string, limit: number = 5): Promise { try { console.log(`📦 [DashboardService] Obtendo pedidos pendentes para role: ${userRole}`); const normalizedRole = userRole?.toLowerCase() const pedidosResponse = normalizedRole === 'admin' ? await pedidoService.listar() : await pedidoService.listar(); const todosPedidos = pedidosResponse.documents || []; // Filtrar pedidos da empresa se não for SUPERADMIN const pedidos = normalizedRole === 'admin' ? todosPedidos : todosPedidos.filter((pedido: any) => pedido.vendedor?.includes(empresaId!) || pedido.comprador === empresaId! ); // Filtrar apenas pedidos pendentes const pedidosPendentes = pedidos .filter((pedido: Documento) => ['pendente', 'aguardando_aprovacao'].includes(pedido.status?.toLowerCase())) .slice(0, limit) .map((pedido: Documento) => ({ id: pedido.$id, numero: `#${pedido.$id.substring(0, 8)}`, status: pedido.status, valor: pedido['valor-total'] || 0, comprador: pedido.comprador || 'N/A', data: pedido.$createdAt, })); return pedidosPendentes; } catch (error) { console.error('❌ [DashboardService] Erro ao obter pedidos pendentes:', error); return []; } } } const dashboardService = new DashboardService(); export default dashboardService;