Calcular saldo anterior

Boa tarde pessoal, beleza?
Seguinte, tenho duas tabelas no meu banco de dados nas quais gravo as movimentações de receitas e despesas.
Mais precisamente as tabelas são: CONTAPAGAR e CONTARECEBER.
Nas duas tabelas eu possuo uma FK_MOVIMENTACAO, que por sua vez, possui uma FK_CONTA para identificar a conta que será movimentada.
O saldo resultante das movimentações em si (débito = CONTAPAGAR e crédito = CONTARECEBER) é tranquilo de se calcular.

QUERIA SABER COMO FAÇO PARA CALCULAR O SALDOANTERIOR ao período definido no FLUXO DE CAIXA!! POR FAVOR, ME AJUDEM!!!

Caio,

Desculpe, mas acho que não entendi direito. Você não tem a data/hora dessas movimentações? Não seria só filtrar através disso?

Tenho sim. Vou tentar melhorar a explicação.

Conta (numeroConta, etc…)
Movimentacao (data, valor, conta, etc…)
ContaPagar (fornecedor, dataVenc, valorVenc, dataPag, valorPag, movimentacao, etc…):
ContaReceber (cliente, dataVenc, valorVenc, dataRec, valorrec, movimentacao, etc…):

Ou seja, uma contaPagar (ou receber) está ligada à uma Movimentação, que por sua vez, está ligada a uma Conta (à qual eu CREDITO ou DEBITO).

Para fazer o FLUXO DE CAIXA, o usuário pode escolher o PERÍODO desejado, a CONTA desejada e FILTRAR…

Para calcular o SALDO FINAL, eu preciso considerar as MOVIMENTAÇÕES DO PERÍODO (Contas a Pagar e Contas a Receber) e TAMBÉM o SALDO ANTERIOR a esse período… Esse SALDO ANTERIOR que eu queria saber como obter.

Sugiro que você mantenha registrado o saldo atualizado após cada movimentação(ou alguma coisa do tipo), desta forma você consegue pegar movimentacao.conta.saldo referente à primeira movimentação seu filtro e fazer o calculo da diferença entre entradas e saidas.
Isso implica em ter que que fazer um pequeno processamento a cada nova movimentação, mas evita um processamento gigantesco quando precisar achar o saldo anterior.

Cara, recomendaria tu criar uma tabela que fosse ligada a esse fluxo de caixa, onde teria um saldo, que seria atualizado, usando uma trigger, a cada inserção de contaPagar ou contaReceber. Daí nessa inserção, tbm seria inserido a data desse novo saldo. Assim, era so fazer a consulta nessa nova tabela com o periodo q tu quisesse.

Espero ter ajudado…

Iae pessoal, obrigado por responderem o/ @Gedson_Silva @dicaminha
Demorei pra responder pq fiquei bloqueado de postar por 9 horas, por conta da política de uso do GUJ para novos usuários, enfim…
Com base nas dicas que me deram. eu criei uma nova tabela FluxoCaixa(conta, data, saldo) -> PK = conta + data. Ou seja, não existem dois registro com mesma data e conta, e o saldo é atualizado de acordo com os lançamentos diários. Pensei em adicionar um novo campo “saldoAnterior”, e tratar ele desde o primeiro registro gerado na tabela.

EXEMPLO:
Data - 22/03/2016
Conta - 99999 Banco Brasil

  1. Existe algum fluxo de caixa para esta conta, ANTERIOR ao dia 22? Se sim, pegar o “saldo” do fluxo encontrado e atualizar no campo “saldoanterior” do fluxo do dia 22, da conta do BB. E assim sucessivamente para os outros dias…

Agora, pensei que o cara pode fazer algum lançamento RETROATIVO, ou seja, que influencie no meu “saldoanterior” JÁ CALCULADO. Agora (2), imagine que já existem vários lançamentos anteriores ao dia 22 … eu teria que sair atualizando TUDO em uma espécie de EFEITO CASCATA??? Então o dilema??? Não sei se estou complicando demais… queria esclarecer melhor as coisas, mas confesso que está complicado!!! SE PUDEREM ME DAR UMA LUZ…

Vlw!

Blz, Caio ? Agora (1), sim, pode haver ( e acontece direto = ) lançamentos retroativos, seja por necessidade ou por erro (como um lançamento feito com data errada, ex., numero do mês digitado errado, teria que ser excluído de um ponto/data do extrato para ser inserido em outro. Agora (2), sim, imagine que sempre terá vários - infinitos - lançamentos anteriores, e, sim, precisará recalculá-los, pode preparar rotinas para isso. Sentiu na pele a (dor) dos analistas dos Conta Corrente dos bancos ? Não tem mágica = ). Complexo, sim. Complicado, não. Tenha um conceito em mente que facilita. Imagine como faria isso no papel primeiro. Como nossos pais e avós fizeram por muito tempo antes dos computadores. Lembro do meu pai me contar que o gerente olhava o SALDO um um BLOCO com 5 dedos de altura de FORMULÁRIO CONTINUO, e só havia UM SALDO POR DIA para toda uma agencia bancária ! Pira = ) Então, pense num livro para cada conta sua. Pense num linha para cada movimento/lançamento de credito ou débito. Livros contábeis são assim: uma linha para cada lançamento, uma 1a primeira coluna para valor crédito, uma 2a segunda coluna para valor débito, e uma 3a terceira coluna para SALDO DO DIA (pode ser ZERO, positivo ou negativo só naquele dia), e uma 4a coluna para SALDO GERAL ou ACUMULADO, que - este sim - leva em conta o SALDO DO DIA ANTERIOR. Pense que, no fim de cada dia ( = fim do expediente bancário ), para cada Conta/Livro-Caixa, VOCÊ, o Hércules ( trampo hercúleo = ), gerente dessa agência, (passa a régua) abaixo da última linha do dia, e faz uma linha de totais: 1a coluna: soma créditos, 2a coluna: soma débitos, 3a coluna: CRED + DEB = movimento do dia, 4a coluna: valor 3a coluna de HOJE, SOMADA com a 4a coluna do dia ANTERIOR. Simule isso numa planilha do MS-Excel ou OpenOffice-Calc (sou do tempo do Lotus-1-2-3 = ), Creio que durante e depois desse exercício conceitual as rotinas/procs/metodos java vao surgindo sozinhas na sua cabeça. Faça primeiro o calculo de saldo diário e confira. Depois simule um lançamento errado (errar é humano, mas um sistema que não facilita a correção do erro é desumano = ), onde um dado movimento (CRED ou DEB) vai MUDAR DE DATA, isto é, excluir da uma data, RECALCULAR saldos, e incluir em outra - que pode ser ANTES OU DEPOIS dessa, atenção nesse detalhe - e RECALCULAR saldos de novo. Sugestão: crie duas funções: ( incluirMovimento( dataYYYYmmDDHHMMSS, valor (com 2 decimais para lidar com grana$), operaçãoCredDeb ) ] e outra [ excluirMovimento( dataYYYYmmDDHHMMSS, valor, operaçãoCredDeb) ]. Assitiu filmes de viagem no tempo, alteração de passado, reflexo no futuro ? Bem isso = ] Divirta-se ! Se conseguir fazer isso, terá um sistema redondinho. Veja que ter as somas parciais prontas para cada dia na 3a coluna vai economizar esforço de não recalcular todos os dias, recalculando apenas os dias onde o movimento foi excluído ou inserido, e depois recalculando a 4a coluna desse dia em diante, até o presente. Quando abrir seu próprio banco quero uma conta com isenção de tarifas, ok ? Pergunte de novo se algo ficou confuso. Tive que fazer esse sistema recentemente para um controle de pontuação. Sugestão: Uma tabela MovimentoPorDataPorConta (alias MOV), uma tabela TotalPorDiaPorConta (alias TOTDIA), uma tabela SaldoDoDiaPorConta (alias SALDODIA). PROIBIDO USAR UPDATE NA TABELA MOVIMENTO ! A cada insert/delete de movimento, independente do diaYYYYmmDD, A coluna Saldo da tabela TotalPorDiaPorConta sera (re)construida com SUM ( (+)MOV.ColunaCredito (-)MOV.ColunaDebito) GROUP BY diaSemHoraYYYYmmDD, numeroConta, numeroAgenciaSeTiver. A coluna Saldo da tabela SaldoDoDiaPorConta = SUM( TOTDIA.Saldo ) GROUP BY dataYYYYmmDD, numeroConta; Resumo: Soma Movimentos e obtem SaldosPorDia, Soma SaldosPorDia e obtem SaldoAtual. Na prática, a cada movimento se recalcula (quase) tudo ! Não se esqueça de me dar isenção de tarifa no seu banco, Sr Banqueiro = ) [ ]´s

Caio, cole isso tudo num editor, separe cada frase por ponto final em uma nova linha, numere essas linhas, leia com calma. Re-pergunte o que faltar por partes usando o numero da frase como referência. Perdão, esqueci de numerar os passos. [ ]´s

Esse negócio é chato mesmo.
Ter uma referência de saldo inicial na sua conta é fundamental mesmo, você provavelmente(quase com certeza) vai passar por coisas do tipo lançamento retroativo.
Esse tipo de lançamento é traumático e costuma gerar problemas do tipo seu sistema não permite lançamentos que gerem valores negativos, vai tudo bem até fazerem um lançamento retroativo que em algum momento negativa algum valorou seja, lançamentos retroativos geram demanda de efeito cascata, mas o efeito cascata pode gerar resultados inesperados.
Tenha em mente a ideia de que você precisa manter o salto atual, o saldo anterior estará no gravado da mesma forma no registro anterior.
Dá uma olhada depois no Hibernate Envers. Ele serve pra fazer auditoria de entidade e suas mudanças, em alguns casos é mais simples você implentar sua lógica de atualização nele e deixar que ele controle o fluxo, uma vez que será mais fácil obter algumas respostas utilizando a API dele do que implementando uma lógica complicada e de processamento caro.

Carrego comigo dois conceitos pra esse tipo de situação complexa:
O primeiro aprendi em um livro chamado Caindo na Real (Getting real) e ele diz (mais ou menos assim), deixa o problema ser problema quando ele for problema.
O segundo é o principio SOLID

Em resumo, mantenha sua estrutura simples e preparada pra mudanças(Programe por interfaces e não por implementação), deixe pra fazer as mudanças quando elas forem necessárias.

Muito obrigado pelas dicas! @esertorio @Gedson_Silva
Era como eu imaginava mesmo. Requer uma atenção especial pela complexidade, mas vamos pra cima o/
@esertorio ótima abordagem cara, você é das minhas (Duda né?) kkk :slight_smile:
@Gedson_Silva separei um material aqui, dei uma lida meio por cima, mas vou estudá-lo posteriormente, muito interessante este esquema de auditoria de entidade.

Enfim, pessoal… por hora, a implementação desta lógica do saldo anterior está em stand by, mas, com as dicas que me deram, quando voltar para implementação dela, acredito que tudo será mais claro!

Obrigado aos dois. Vlw

PS: Além da isenção de tarifas, vou caprichar no saldo inicial da conta dos dois kkk @esertorio

1 curtida