@@ -927,9 +927,12 @@ function PaginaDashboard({ espaco, ano, mesIdx, escuro, irPara }) {
927927 const receitasMes = soma ( doMes . filter ( ( t ) => t . tipo === "receita" && t . status === "ok" ) ) ;
928928 const despesasMes = soma ( doMes . filter ( ( t ) => t . tipo === "despesa" && t . status === "ok" ) ) ;
929929 const lucro = receitasMes - despesasMes ;
930- const saldoAtual =
931- soma ( ts . filter ( ( t ) => t . tipo === "receita" && t . status === "ok" ) ) -
932- soma ( ts . filter ( ( t ) => t . tipo === "despesa" && t . status === "ok" ) ) ;
930+ // saldo acumulado: tudo que entrou − saiu até o FIM do mês selecionado,
931+ // carregando o resultado (positivo ou negativo) para os meses seguintes
932+ const fimMes = prefixo + "-31" ;
933+ const saldoAcumulado =
934+ soma ( ts . filter ( ( t ) => t . tipo === "receita" && t . status === "ok" && t . data <= fimMes ) ) -
935+ soma ( ts . filter ( ( t ) => t . tipo === "despesa" && t . status === "ok" && t . data <= fimMes ) ) ;
933936
934937 // comparação com o mês anterior
935938 let pa = mesIdx - 1 , py = ano ;
@@ -977,10 +980,10 @@ function PaginaDashboard({ espaco, ano, mesIdx, escuro, irPara }) {
977980 < div className = "grid grid-cols-2 gap-3 lg:grid-cols-4" >
978981 < StatCard
979982 icon = { Wallet }
980- label = "Saldo atual "
981- value = { fmtBRL ( saldoAtual ) }
982- tone = { saldoAtual >= 0 ? "default" : "bad" }
983- sub = " Tudo que entrou − saiu"
983+ label = "Saldo acumulado "
984+ value = { fmtBRL ( saldoAcumulado ) }
985+ tone = { saldoAcumulado >= 0 ? "default" : "bad" }
986+ sub = { ` Tudo até ${ MESES_CURTO [ mesIdx ] } / ${ ano } , mês a mês` }
984987 />
985988 < StatCard icon = { TrendingUp } label = "Receitas do mês" value = { fmtBRL ( receitasMes ) } sub = { varPct ( receitasMes , recAnt ) } />
986989 < StatCard icon = { TrendingDown } label = "Despesas do mês" value = { fmtBRL ( despesasMes ) } sub = { varPct ( despesasMes , despAnt ) } />
@@ -1602,11 +1605,17 @@ function PaginaRelatorios({ espaco, empresarial, ano, mesIdx, nomeApp }) {
16021605 }
16031606
16041607 // ---- dados anuais ----
1608+ // saldo que vem dos anos anteriores (carrega resultado, mesmo negativo)
1609+ const saldoAnterior =
1610+ soma ( ts . filter ( ( t ) => t . tipo === "receita" && t . data < `${ ano } -01-01` ) ) -
1611+ soma ( ts . filter ( ( t ) => t . tipo === "despesa" && t . data < `${ ano } -01-01` ) ) ;
1612+ let acumulado = saldoAnterior ;
16051613 const anual = MESES . map ( ( nome , i ) => {
16061614 const p = mesPrefixo ( ano , i ) ;
16071615 const rec = soma ( ts . filter ( ( t ) => t . tipo === "receita" && t . data . startsWith ( p ) ) ) ;
16081616 const desp = soma ( ts . filter ( ( t ) => t . tipo === "despesa" && t . data . startsWith ( p ) ) ) ;
1609- return { nome, rec, desp, lucro : rec - desp } ;
1617+ acumulado += rec - desp ;
1618+ return { nome, rec, desp, lucro : rec - desp , acumulado } ;
16101619 } ) ;
16111620 const totAnualRec = anual . reduce ( ( a , m ) => a + m . rec , 0 ) ;
16121621 const totAnualDesp = anual . reduce ( ( a , m ) => a + m . desp , 0 ) ;
@@ -1650,14 +1659,15 @@ ${empresarial ? `<h2>Despesas por centro de custo</h2>${htmlTabela(["Centro de c
16501659 const titulo = `Relatório anual — ${ ano } (${ escopo } )` ;
16511660 if ( formato === "pdf" ) {
16521661 const corpo = `<h1>${ nomeApp } </h1><p class="sub">${ titulo } </p>
1653- ${ htmlTabela ( [ "Mês" , "Receitas" , "Despesas" , "Lucro" ] , anual . map ( ( m ) => [ m . nome , fmtBRL ( m . rec ) , fmtBRL ( m . desp ) , fmtBRL ( m . lucro ) ] ) , [ "Total" , fmtBRL ( totAnualRec ) , fmtBRL ( totAnualDesp ) , fmtBRL ( totAnualRec - totAnualDesp ) ] ) } `;
1662+ ${ saldoAnterior !== 0 ? `<p class="sub">Saldo vindo dos anos anteriores: ${ fmtBRL ( saldoAnterior ) } </p>` : "" }
1663+ ${ htmlTabela ( [ "Mês" , "Receitas" , "Despesas" , "Lucro" , "Acumulado" ] , anual . map ( ( m ) => [ m . nome , fmtBRL ( m . rec ) , fmtBRL ( m . desp ) , fmtBRL ( m . lucro ) , fmtBRL ( m . acumulado ) ] ) , [ "Total" , fmtBRL ( totAnualRec ) , fmtBRL ( totAnualDesp ) , fmtBRL ( totAnualRec - totAnualDesp ) , fmtBRL ( anual [ 11 ] . acumulado ) ] ) } `;
16541664 exportarPDF ( titulo , corpo ) ;
16551665 } else {
16561666 exportarExcel ( `relatorio-${ escopo . toLowerCase ( ) } -${ ano } ` , [
16571667 [ titulo ] , [ ] ,
1658- [ "Mês" , "Receitas" , "Despesas" , "Lucro" ] ,
1659- ...anual . map ( ( m ) => [ m . nome , fmtNum ( m . rec ) , fmtNum ( m . desp ) , fmtNum ( m . lucro ) ] ) ,
1660- [ "Total" , fmtNum ( totAnualRec ) , fmtNum ( totAnualDesp ) , fmtNum ( totAnualRec - totAnualDesp ) ] ,
1668+ [ "Mês" , "Receitas" , "Despesas" , "Lucro" , "Acumulado" ] ,
1669+ ...anual . map ( ( m ) => [ m . nome , fmtNum ( m . rec ) , fmtNum ( m . desp ) , fmtNum ( m . lucro ) , fmtNum ( m . acumulado ) ] ) ,
1670+ [ "Total" , fmtNum ( totAnualRec ) , fmtNum ( totAnualDesp ) , fmtNum ( totAnualRec - totAnualDesp ) , fmtNum ( anual [ 11 ] . acumulado ) ] ,
16611671 ] ) ;
16621672 }
16631673 }
@@ -1745,7 +1755,8 @@ ${htmlTabela(["Mês", "Receitas", "Despesas", "Lucro"], anual.map((m) => [m.nome
17451755 < th className = "py-2 pr-2" > Mês</ th >
17461756 < th className = "py-2 pr-2 text-right" > Receitas</ th >
17471757 < th className = "py-2 pr-2 text-right" > Despesas</ th >
1748- < th className = "py-2 text-right" > Lucro</ th >
1758+ < th className = "py-2 pr-2 text-right" > Lucro</ th >
1759+ < th className = "py-2 text-right" > Acumulado</ th >
17491760 </ tr >
17501761 </ thead >
17511762 < tbody className = "divide-y divide-slate-50 dark:divide-slate-800" >
@@ -1756,25 +1767,45 @@ ${htmlTabela(["Mês", "Receitas", "Despesas", "Lucro"], anual.map((m) => [m.nome
17561767 < td className = "py-2 pr-2 text-right tabular-nums text-red-500" > { m . desp ? fmtBRL ( m . desp ) : "—" } </ td >
17571768 < td
17581769 className = {
1759- "py-2 text-right font-medium tabular-nums " +
1770+ "py-2 pr-2 text-right font-medium tabular-nums " +
17601771 ( m . lucro > 0 ? "text-emerald-600" : m . lucro < 0 ? "text-red-500" : "text-slate-400" )
17611772 }
17621773 >
17631774 { m . rec || m . desp ? fmtBRL ( m . lucro ) : "—" }
17641775 </ td >
1776+ < td
1777+ className = {
1778+ "py-2 text-right font-semibold tabular-nums " +
1779+ ( m . acumulado >= 0 ? "text-slate-700 dark:text-slate-200" : "text-red-500" )
1780+ }
1781+ >
1782+ { fmtBRL ( m . acumulado ) }
1783+ </ td >
17651784 </ tr >
17661785 ) ) }
17671786 < tr className = "font-bold" >
17681787 < td className = "py-2 pr-2 text-slate-700 dark:text-slate-200" > Total</ td >
17691788 < td className = "py-2 pr-2 text-right tabular-nums text-emerald-600" > { fmtBRL ( totAnualRec ) } </ td >
17701789 < td className = "py-2 pr-2 text-right tabular-nums text-red-500" > { fmtBRL ( totAnualDesp ) } </ td >
1771- < td className = "py-2 text-right tabular-nums text-slate-700 dark:text-slate-200" >
1790+ < td className = "py-2 pr-2 text-right tabular-nums text-slate-700 dark:text-slate-200" >
17721791 { fmtBRL ( totAnualRec - totAnualDesp ) }
17731792 </ td >
1793+ < td
1794+ className = {
1795+ "py-2 text-right tabular-nums " +
1796+ ( anual [ 11 ] . acumulado >= 0 ? "text-slate-700 dark:text-slate-200" : "text-red-500" )
1797+ }
1798+ >
1799+ { fmtBRL ( anual [ 11 ] . acumulado ) }
1800+ </ td >
17741801 </ tr >
17751802 </ tbody >
17761803 </ table >
17771804 </ div >
1805+ < p className = "mt-2 text-xs text-slate-400" >
1806+ O "Acumulado" carrega o resultado de cada mês para o seguinte, mesmo quando negativo
1807+ { saldoAnterior !== 0 ? `, incluindo ${ fmtBRL ( saldoAnterior ) } vindos dos anos anteriores` : "" } .
1808+ </ p >
17781809 </ Card >
17791810 ) }
17801811 </ div >
0 commit comments