A contabilidade de entrada dupla é
um conjunto de regras para o registro de informações financeiras em um sistema de contabilidade financeira no qual cada transação ou evento altera pelo menos duas contas contábeis nominais diferentes.
Uma conta pode ser "debitada" ou "creditada", e a soma de todos os créditos deve ser igual à soma de todos os débitos.
Como você implementaria isso em um banco de dados Postgres? Especificando o seguinte DDL:
CREATE TABLE accounts(
account_id serial NOT NULL PRIMARY KEY,
account_name varchar(64) NOT NULL
);
CREATE TABLE transactions(
transaction_id serial NOT NULL PRIMARY KEY,
transaction_date date NOT NULL
);
CREATE TABLE transactions_details(
id serial8 NOT NULL PRIMARY KEY,
transaction_id integer NOT NULL
REFERENCES transactions (transaction_id)
ON UPDATE CASCADE
ON DELETE CASCADE
DEFERRABLE INITIALLY DEFERRED,
account_id integer NOT NULL
REFERENCES accounts (account_id)
ON UPDATE CASCADE
ON DELETE RESTRICT
NOT DEFERRABLE INITIALLY IMMEDIATE,
amount decimal(19,6) NOT NULL,
flag varchar(1) NOT NULL CHECK (flag IN ('C','D'))
);
Nota: a tabela transaction_details não especifica uma conta explícita de débito / crédito, porque o sistema deve poder debitar / creditar mais de uma conta em uma única transação.
Essa DDL cria o seguinte requisito: Depois que uma transação do banco de dados é confirmada na tabela transaction_details, ela deve debitar e creditar o mesmo valor para cada uma transaction_id
, por exemplo :
INSERT INTO accounts VALUES (100, 'Accounts receivable');
INSERT INTO accounts VALUES (200, 'Revenue');
INSERT INTO transactions VALUES (1, CURRENT_DATE);
-- The following must succeed
BEGIN;
INSERT INTO transactions_details VALUES (DEFAULT, 1, 100, '1000'::decimal, 'D');
INSERT INTO transactions_details VALUES (DEFAULT, 1, 200, '1000'::decimal, 'C');
COMMIT;
-- But this must raise some error
BEGIN;
INSERT INTO transactions_details VALUES (DEFAULT, 1, 100, '1000'::decimal, 'D');
INSERT INTO transactions_details VALUES (DEFAULT, 1, 200, '500'::decimal, 'C');
COMMIT;
É possível implementar isso em um banco de dados PostgreSQL? Sem especificar tabelas adicionais para armazenar estados de disparo.