Estou criando um software de contabilidade. Preciso fazer valer a escrituração de partidas dobradas. Eu tenho o problema clássico de uma linha por transação versus duas linhas.
Vamos dar um exemplo e ver como ele seria implementado em ambos os cenários.
Considere conta Cash
e conta Rent
. Quando pago meu aluguel mensal, transfiro $ 100 da minha Cash
conta para minha Rent
conta.
Uma linha por transação
Em um sistema de uma linha, essa transação seria armazenada como:
transações
tx_id | posting_date
1 | 23/05/2015
registros_transação
id | tx_id | credit_account | debit_account | amount
1 | 1 | Cash | Rent | 100.00
Duas linhas por transação
Em um sistema de duas linhas, eu teria que espelhar o mesmo registro de transação para criar um registro oposto que, uma vez que eu somasse ambos, obteria saldo zero.
transações
tx_id | posting_date
1 | 23/05/2015
registros_transação
id | tx_id | type | account | amount
1 | 1 | credit | Cash | 100.00
2 | 1 | debit | Rent | 100.00
O problema
Antes de tudo, gostaria de observar: a razão pela qual tenho ambas as tabelas transactions
e transaction_records
(em vez de uma tabela) é poder lidar com transações divididas (um caso em que transfiro $ 100 de uma Cash
conta para duas ou mais contas diferentes).
No começo, tentei implementar isso com uma linha por transação, mas é difícil calcular o saldo da conta e realmente recuperar os dados.
Estou inclinado para o segundo cenário; no entanto, também tem alguns problemas:
- Como atualizo um único registro? Supondo que cometi um erro e, em vez de registrar $ 100 para meu aluguel, registrei $ 10. Agora tenho 2
transaction_records
- um para crédito e outro para débito, ambos com valor de $ 10. - Agora faço minha reconciliação e quero corrigir esse erro de digitação. Como eu corrigiria isso no banco de dados? Não conheço a conexão entre os registros, e em caso de divisão, uma transação pode ter mais de 2 registros. A única solução que encontrei é adicionar alguns
ref_id
para cada par de registros que identificará exclusivamente esses registros como sendo os "lados opostos um do outro" dentro de um contexto de um arquivotx_id
.
Qual abordagem é melhor/mais simples?
Para simplificar minha pergunta: quero representar um movimento de fundos da conta A para a conta B. Os dois cenários que dei são designs válidos para armazenar essa transação. Como também apontei, ambos têm contras e prós (primeiro: mais fácil de salvar, mais difícil de recuperar; segundo, o oposto).
Eles podem ter outros prós/contras que eu não identifiquei agora, por isso peço a opinião de pessoas mais experientes.
Um Diário é uma listagem cronológica de todas as transações de um tipo específico para um sistema de contabilidade. Aqui está uma apresentação clássica em papel razão de um simples Diário de Vendas (por Conta):
Observe que cada linha é uma única transação, com Total de Débitos = Total de Créditos; e que cada transação atinge as mesmas três contas. Um Diário de vendas à vista seria semelhante, mas substituiria a coluna Débito de contas a receber por uma etiqueta Débito à vista . Um Diário de Desembolsos em Dinheiro teria uma primeira coluna denominada Crédito em Dinheiro e colunas adicionais, como Débito de Contas a Pagar e Débito de Despesas de Empregados .
Essa apresentação foi padrão por centenas de anos até que os computadores pessoais se tornaram acessíveis há algumas décadas. Ele tem a vantagem significativa de verificar facilmente se todas as transações estão balanceadas simplesmente verificando cada linha. Da mesma forma, antes de publicar uma página de tal transação nos Livros , os totais da página podem ser verificados da mesma forma. Esse é um modelo de processamento em lote usado em muitos sistemas de contabilidade.
É fácil ver que este modelo de papel apresenta desvantagens significativas quando transcrito literalmente para um sistema automatizado:
Por essas razões, geralmente é recomendado usar o design de Periódicos Especializados como interface para o sistema contábil, mas projetar uma estrutura de dados que possa ser o repositório numérico de vários periódicos. Em um RDBMS moderno, isso tem a vantagem potencial de que o General Ledger , e até os subledgers especializados , podem se tornar Indexed Views no Journal, eliminando completamente a necessidade de codificar um Processo de Lançamento (a etapa em que uma transação do Journal é bloqueada e tem sua conta totais transcritos para os vários livros).
Qualquer que seja o design de dados que você tenha, a chave é ter uma única entrada de lançamento para cada tipo de transação (ou seja, cada diário especializado no sistema de papel equivalente) onde as verificações de saldo são feitas.
Meu ponto é que ambas as abordagens que você propõe são mecanismos infundados para a contabilidade de partidas dobradas. Primeiro ponto: Os diários são tabelas de escrita única por boas razões. Às vezes, as duas tabelas virtuais Pending Entries e Posted Entries são colocadas em uma única estrutura de dados, mas o bit IsPosted é sempre somente gravação e o sistema deve garantir que a natureza somente leitura dos registros Posted Entries seja mantida.
A forma como os contadores publicaram lançamentos contábeis nos últimos 800 anos está totalmente normalizada . A única diferença entre uma apresentação em papel e uma apresentação eletrônica de som é que uma estrutura de mesa dobrada é mais conveniente no último caso, enquanto uma estrutura de mesa giratória no primeiro caso, que historicamente era mais significativa quando se desejava um processamento altamente paralelo - ou seja, muitos funcionários cada manter um único ou pequeno número de periódicos especializados. Apenas o Controlador historicamente tinha permissões para o Diário Geral.
Observe cuidadosamente que no acima eu especifiquei que as entradas de diário são totalmente normalizadas; Diários são um registro cronológico de todas as transações, agrupadas em Diários específicos para cada tipo de transação. O lançamento de lançamentos contábeis nos livros contábeis é um esforço separado e, embora totalmente normalizado por conta própria, é uma cópia redundante dos lançamentos contábeis manuais em que todas as transações são resumidas (razão geral) ou detalhadas (sub-razão) por conta. Tanto os Journals quanto os Ledgers empregam a contabilidade de partidas dobradas de forma independente.
@Codism Qualquer sistema de contabilidade, DEB ou SEB, fornece relatórios generalizados para todas as contas registradas . Observe que, internamente, um livro auxiliar é, por definição, um registro contábil de entrada única; o outro lado é a (s) conta(s) de controle correspondente(s) no Balanço Patrimonial. O DEB garante que para cada dólar de ativo haja um registro preciso da reivindicação comercial sobre o ativo , ou seja, o patrimônio no ativo, seja um patrimônio líquido (também conhecido como passivo) ou um patrimônio líquido , e da prioridade dessas reivindicações se o organização torna-se insolvente.
De fato, o esquema de contabilidade de linha única proposto permite fazer uma contabilidade de dupla entrada adequada (para especificar sempre a conta debitada e creditada) sem introduzir a redundância dos dados de "quantidade".
O esquema de uma linha fornece uma implementação de uma entrada dupla que equilibra por construção, de modo que é impossível "perder o saldo". A máquina pode recalcular os livros em tempo real.
Você tem que fazer 2 select em vez de um para recuperar um livro.
Observe que, além da divisão de transações, existem outras transações, como câmbio, que podem acabar com 2 registros em vez de 4. Tudo depende se você desnormalizar um pouco, basta inserir 4 transações com descrição semelhante.
Você pode impedir a entrada ou modificação de qualquer transação para manter uma trilha de auditoria, isso é necessário se você quiser auditar o log de transações.
Parece que no tópico acima, para o CPA, "totalmente normalizado" parece significar regras reconhecidas por todos os contadores, enquanto para o programador tem um significado diferente, que não há dados derivados ou redundantes armazenados.
Para os dados contabilísticos, basta um conjunto de transacções que dão o montante e as contas de onde e para as quais fluem, juntamente com a sua data, alguma descrição (e outros anexos). Razões e saldos são visualizações simples derivadas desses dados transacionais por meio de somas.
Posso sugerir que você dê uma olhada no tesouro de software de código aberto que existe nessa área?
Um Google de " software de contabilidade de dupla entrada de código aberto " oferece vários caminhos promissores de investigação.
Você pode ver o pacote de contabilidade GNU aqui , alguns sites de revisão ( 1 e 2 ) e finalmente o wiki de software de contabilidade com uma seção sobre Software Livre.
Tenho certeza de que, examinando alguns dos códigos e esquemas-fonte do F/LOSS, você poderá obter algumas boas dicas e indicações de como escrever esquemas e/ou software que atendam às suas necessidades específicas.
Eu tenho um sistema que faz linhas duplas e seus muitos desafios do que ter contas de linhas únicas. Primeiro, encontrei casos de apenas uma linha sendo empurrada como o lado do débito, resultando em conta desequilibrada. Mesmo se não estiver fazendo os controles adequados de confirmação e reversões, isso não aconteceria em contas de uma única linha. por último, seu db cresce em taxa de crescimento dupla, sua segunda linha de envio terá muitas informações duplicadas, a única diferença sendo a segunda conta. Aconselharia manter, conta de linha única, estou indo para esse caminho..