import React, { useState, useMemo } from 'react'; import { FinancialReportType, Expense, Receivable } from '../types'; import { Download, Printer, Filter, ChevronRight, X, Calendar, Building2, CheckCircle2, FileText } from 'lucide-react'; import { useToast } from '../contexts/ToastContext'; import { CustomSelect } from './CustomSelect'; interface FinancialReportsViewProps { expenses: Expense[]; receivables: Receivable[]; } const ReportTab = ({ active, label, onClick }: { active: boolean, label: string, onClick: () => void }) => ( ); const TableRow = ({ label, value, indent = 0, isTotal = false, isHeader = false }: { label: string, value: string | React.ReactNode, indent?: number, isTotal?: boolean, isHeader?: boolean }) => (
{label} {value}
); export const FinancialReportsView: React.FC = ({ expenses, receivables }) => { const { addToast } = useToast(); const [activeTab, setActiveTab] = useState('DRE'); const [showFilters, setShowFilters] = useState(false); const [filters, setFilters] = useState({ period: 'mensal', costCenter: 'Todos' }); const handleExport = () => { addToast({ type: 'info', title: 'Gerando PDF...', message: 'O download iniciará em instantes.', duration: 2000 }); setTimeout(() => { addToast({ type: 'success', title: 'Exportação Concluída', message: `Relatório ${activeTab} salvo com sucesso.` }); }, 2000); }; // --- ACCOUNTING ENGINE (Cálculos Reais) --- const reportData = useMemo(() => { // 1. Data Preparation const paidRevenue = receivables.filter(r => r.status === 'paid').reduce((sum, r) => sum + r.value, 0); const pendingRevenue = receivables.filter(r => r.status === 'pending').reduce((sum, r) => sum + r.value, 0); const totalRevenue = paidRevenue + pendingRevenue; // Competência const paidExpenses = expenses.filter(e => e.status === 'paid'); const pendingExpenses = expenses.filter(e => e.status === 'pending'); // Categorização de Despesas Pagas const taxExpenses = paidExpenses.filter(e => e.category === 'Impostos').reduce((sum, e) => sum + e.amount, 0); const costExpenses = paidExpenses.filter(e => e.category === 'Operacional').reduce((sum, e) => sum + e.amount, 0); // Mocking Op as CMV/CPV const adminExpenses = paidExpenses.filter(e => e.category === 'Administrativo' || e.category === 'TI').reduce((sum, e) => sum + e.amount, 0); const salesExpenses = paidExpenses.filter(e => e.category === 'Marketing').reduce((sum, e) => sum + e.amount, 0); const personnelExpenses = paidExpenses.filter(e => e.category === 'Pessoal').reduce((sum, e) => sum + e.amount, 0); // Totais const totalDeductions = taxExpenses; // Simplificação const netRevenue = paidRevenue - totalDeductions; const grossProfit = netRevenue - costExpenses; const totalOpExpenses = adminExpenses + salesExpenses + personnelExpenses; const netIncome = grossProfit - totalOpExpenses; // 2. Balance Sheet (BP) Calculations (Estimated) // Assets const cashAndEquivalents = 50000 + (netIncome > 0 ? netIncome : 0); // Mock Start Cash + Profit const accountsReceivable = pendingRevenue; const fixedAssets = 150000; // Mocked Fixed Assets (Computers, Furniture) const totalCurrentAssets = cashAndEquivalents + accountsReceivable; const totalNonCurrentAssets = fixedAssets; const totalAssets = totalCurrentAssets + totalNonCurrentAssets; // Liabilities const accountsPayable = pendingExpenses.reduce((sum, e) => sum + e.amount, 0); const loansShortTerm = 20000; // Mock const loansLongTerm = 100000; // Mock const totalCurrentLiabilities = accountsPayable + loansShortTerm; const totalNonCurrentLiabilities = loansLongTerm; // Equity const shareCapital = 50000; // Mock const retainedEarnings = totalAssets - (totalCurrentLiabilities + totalNonCurrentLiabilities + shareCapital); // Balancing figure const totalEquity = shareCapital + retainedEarnings; // 3. Cash Flow (DFC) - Direct Method Simplified const cashInflow = paidRevenue; const cashOutflowOp = paidExpenses.reduce((sum, e) => sum + e.amount, 0); const netCashOperating = cashInflow - cashOutflowOp; // 4. Value Added (DVA) const inputs = costExpenses + adminExpenses + salesExpenses; // Consumo de terceiros const grossValueAdded = paidRevenue - inputs; const netValueAdded = grossValueAdded; // Assuming no depreciation for simplicity return { dre: { grossRevenue: paidRevenue, taxes: taxExpenses, netRevenue, costs: costExpenses, grossProfit, adminExpenses, salesExpenses, personnelExpenses, netIncome }, bp: { cashAndEquivalents, accountsReceivable, totalCurrentAssets, fixedAssets, totalAssets, accountsPayable, loansShortTerm, totalCurrentLiabilities, loansLongTerm, shareCapital, retainedEarnings, totalEquityAndLiabilities: totalCurrentLiabilities + totalNonCurrentLiabilities + totalEquity }, dfc: { netCashOperating, cashInflow, cashOutflowOp }, dva: { grossRevenue: paidRevenue, inputs, grossValueAdded, personnelExpenses, taxExpenses, rentals: 0, equityRemuneration: netIncome } }; }, [expenses, receivables]); const formatCurrency = (val: number) => val.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' }); const formatNegative = (val: number) => `(${formatCurrency(val)})`; const periodLabel = filters.period === 'anual' ? '2024' : filters.period === 'trimestral' ? '1º Trimestre 2024' : 'Maio/2024'; const renderContent = () => { switch (activeTab) { case 'DRE': return (

Demonstração do Resultado do Exercício (DRE)

Período: {periodLabel} | Centro de Custo: {filters.costCenter}

= LUCRO / PREJUÍZO LÍQUIDO {formatCurrency(reportData.dre.netIncome)}
); case 'BP': return (
{/* ATIVO */}
ATIVO
TOTAL DO ATIVO {formatCurrency(reportData.bp.totalAssets)}
{/* PASSIVO */}
PASSIVO E PATRIMÔNIO LÍQUIDO
TOTAL PASSIVO + PL {formatCurrency(reportData.bp.totalEquityAndLiabilities)}
); case 'DFC': return (

Demonstração do Fluxo de Caixa (Método Direto)

Período: {periodLabel}

= 0 ? 'bg-green-50 text-green-800' : 'bg-red-50 text-red-800'}`}> AUMENTO/REDUÇÃO LÍQUIDA DE CAIXA {formatCurrency(reportData.dfc.netCashOperating)}
); case 'DLPA': return (

Demonstração de Lucros ou Prejuízos Acumulados (DLPA)

SALDO FINAL {formatCurrency(reportData.bp.retainedEarnings)}
); case 'DMPL': return (

Demonstração das Mutações do Patrimônio Líquido (DMPL)

Histórico Capital Social Reservas de Lucro Lucros Acumulados Total
Saldo Inicial {formatCurrency(reportData.bp.shareCapital)} R$ 0,00 {formatCurrency(reportData.bp.retainedEarnings - reportData.dre.netIncome)} {formatCurrency(reportData.bp.shareCapital + (reportData.bp.retainedEarnings - reportData.dre.netIncome))}
Lucro Líquido do Período - - {formatCurrency(reportData.dre.netIncome)} {formatCurrency(reportData.dre.netIncome)}
Saldo Final {formatCurrency(reportData.bp.shareCapital)} R$ 0,00 {formatCurrency(reportData.bp.retainedEarnings)} {formatCurrency(reportData.bp.shareCapital + reportData.bp.retainedEarnings)}
); case 'DRA': return (

Demonstração do Resultado Abrangente (DRA)

RESULTADO ABRANGENTE TOTAL {formatCurrency(reportData.dre.netIncome)}
); case 'DVA': return (

Demonstração do Valor Adicionado (DVA)

6. DISTRIBUIÇÃO DO VALOR ADICIONADO
TOTAL DISTRIBUÍDO {formatCurrency(reportData.dva.personnelExpenses + reportData.dva.taxExpenses + reportData.dva.rentals + reportData.dva.equityRemuneration)}
); default: return null; } }; return (

Demonstrações Contábeis

Relatórios gerados em tempo real com base nos lançamentos.

{/* Filter Panel */} {showFilters && (
setFilters({...filters, period: val})} options={[ { value: 'mensal', label: 'Mensal (Mês Atual)' }, { value: 'trimestral', label: 'Trimestral' }, { value: 'semestral', label: 'Semestral' }, { value: 'anual', label: 'Anual (Acumulado)' } ]} />
setFilters({...filters, costCenter: val})} options={[ { value: 'Todos', label: 'Todos' }, { value: 'Administrativo', label: 'Administrativo' }, { value: 'Comercial', label: 'Comercial / Vendas' }, { value: 'Operacional', label: 'Operacional' }, { value: 'TI', label: 'Tecnologia (TI)' } ]} />
)} {/* Tabs */}
setActiveTab('DRE')} /> setActiveTab('BP')} /> setActiveTab('DFC')} /> setActiveTab('DLPA')} /> setActiveTab('DMPL')} /> setActiveTab('DRA')} /> setActiveTab('DVA')} />
{renderContent()}
); };