/* ============================================================ EMPRESA > FINANCEIRO > CAIXA (guias + editar/excluir) Agora com status de pagamento real, lançamentos retroativos e geração automática de cobranças futuras conforme periodicidade. ============================================================ */ function FinCaixaList({ entries, onEdit, onDelete, onMarcarPago, onDownloadAnexo }){ const [filtroAno, setFiltroAno] = useState('todos'); const [busca, setBusca] = useState(''); const anos = Array.from(new Set(entries.map(e=>e.vencimento.slice(0,4)))).sort().reverse(); const withRef = entries.map(e=>({ ...e, ref:mesReferencia(e.vencimento), statusEfetivo:statusEfetivoCaixa(e) })); let filtrados = withRef; if(filtroAno!=='todos') filtrados = filtrados.filter(e=>e.vencimento.slice(0,4)===filtroAno); if(busca) filtrados = filtrados.filter(e=>e.cliente.toLowerCase().includes(busca.toLowerCase())); const sorted = [...filtrados].sort((a,b)=>b.vencimento.localeCompare(a.vencimento)); return (

Boletos & Notas Fiscais Lançados

setBusca(e.target.value)}/>
{sorted.map(e=>( ))} {sorted.length===0 && }
ClienteValorVencimentoAnexosStatus
{e.cliente} {fmtBRL(e.valor)} {new Date(e.vencimento+'T00:00:00').toLocaleDateString('pt-BR')} {e.anexos && e.anexos.boleto &&
} {e.anexos && e.anexos.nota &&
} {(!e.anexos || (!e.anexos.boleto && !e.anexos.nota)) && }
{STATUS_PAGAMENTO_LABELS[e.statusEfetivo]} {e.status==='pago' &&
em {new Date(e.dataPagamento+'T00:00:00').toLocaleDateString('pt-BR')}
}
{e.statusEfetivo!=='pago' && }
Nenhum lançamento encontrado.
); } function FinCaixaForm({ editingEntry, clientes, onSave, onCancel }){ const [clienteId,setClienteId]=useState(editingEntry?.clienteId || (clientes[0]&&clientes[0].id) || ''); const [valor,setValor]=useState(editingEntry? String(editingEntry.valor) : ''); const [vencimento,setVencimento]=useState(editingEntry?.vencimento || ''); const [status,setStatus]=useState(editingEntry?.status || 'pendente'); const [dataPagamento,setDataPagamento]=useState(editingEntry?.dataPagamento || new Date().toISOString().slice(0,10)); const boletoRef = useRef(); const nfRef = useRef(); function submit(e){ e.preventDefault(); if(!valor || !vencimento) return; const boletoFile = boletoRef.current.files[0] || null; const notaFile = nfRef.current.files[0] || null; onSave({ clienteId, valor:parseFloat(valor), vencimento, status, dataPagamento: status==='pago' ? dataPagamento : null, boletoFile, notaFile, anexosAtuais: editingEntry?.anexos || null, }); } return (

{editingEntry ? 'Editar Lançamento' : 'Novo Lançamento'}

setValor(e.target.value)} placeholder="0,00" required/>
setVencimento(e.target.value)} required/>

Pode lançar datas de meses anteriores normalmente — útil para completar o histórico e gerar comparativos do ano.

{status==='pago' && (
setDataPagamento(e.target.value)} required/>
)}
); } function PageFinCaixa({ caixa, clientes, onSave, onDelete, onMarcarPago, onGerarCobrancas, onDownloadAnexo }){ const [view, setView] = useState('lista'); const [editing, setEditing] = useState(null); const editingEntry = editing ? caixa.find(e=>e.id===editing) : null; const withStatus = caixa.map(e=>({ ...e, statusEfetivo:statusEfetivoCaixa(e), ref:mesReferencia(e.vencimento) })); const recebidoMes = withStatus.filter(e=>e.statusEfetivo==='pago' && e.ref.group==='atual').reduce((s,e)=>s+e.valor,0); const aReceberMes = withStatus.filter(e=>(e.statusEfetivo==='pendente') && e.ref.group==='atual').reduce((s,e)=>s+e.valor,0); const atrasado = withStatus.filter(e=>e.statusEfetivo==='atrasado').reduce((s,e)=>s+e.valor,0); return (
e.statusEfetivo==='atrasado').length+' lançamento(s)'} dir={atrasado>0?'down':'up'}/>
{view==='lancamento' ? { onSave(data, editing); setView('lista'); setEditing(null); }} onCancel={()=>{setView('lista'); setEditing(null);}}/> : {setEditing(id); setView('lancamento');}} onDelete={onDelete} onMarcarPago={onMarcarPago} onDownloadAnexo={onDownloadAnexo}/> }
); }