2 ms·
One good technical reason to prefer double entry and relating to the "it helped avoid mistakes [in hand-writing ledgers]" is that double entry patterns encourag
by WorldMaker 4y ago
One good technical reason to prefer double entry and relating to the "it helped avoid mistakes [in hand-writing ledgers]" is that double entry patterns encourage better database transaction discipline and provide helpful debugging clues when database transactions half-finish and accidentally commit rather than rollback. Atomic database transactions with single row inserts of accounting transactions are obviously simpler to build, but it also means you are less likely to test multi-row database transactions such as scenarios where you need to make sure an accounting transaction lands in an atomic commit with say a purchasing invoice row. Double entry accounting, especially when different types of accounts may be in different tables forces your codebase to use good database transactions and sometimes more thorough testing of your commit versus rollback code paths.
Also, in my experience double-entry tables are often much easier to DB query because the tables "naturally" look exactly like the ledgers accountants expect to see in reports. The math in aggregate queries is often just SUM and nothing else, no complicated case logic for "different transaction types" or complicated pivots from transactions to account views and back.
- skipants 4y agoNot sure I follow: you're claiming that double entry forces you to write things with better transactions in mind but the only difference between the two is having 1 vs. 2 rows. Say we have a hotel reservation system, it looks like this in my proposition: 1. Wrap a transaction around rows 2. Add reservation event 3. Add one ledger row for payment 4. Add one ledger row for tax vs. double entry: 1. Wrap a transaction around rows: 2. Add reservation event 3. Add two ledger rows for payment 4. Add two ledger rows for tax
- WorldMaker 4y agoYou can think of double entry as: 1. Create a reservation liability (invoice) [debit the reservation cost] 2. Create a tax liability (tax account) The preceding may happen asynchronously ahead of the time. The following are generally wrapped in a single database transaction: 3. Credit a user's account for value of (total) payment (3a. Depending on how deep your double-entry goes, Debit your Payment Processor) 4. Debit the user's account the reservation amount 5. Credit the reservation account the reservation amount (reservation invoice account should sum to 0 now: no assets, nothing liable) 6. Add reservation event for completed invoice 7. Debit the user's account the tax amount 8. Credit the tax account the tax amount (user's account should sum to 0 now: no assets, nothing liable) It's been a while since I've worked on a system in this mindset, so apologies if I've got subtle things wrong or debit/credit backwards. That's still too easy to do even when you've done it a million times and even when you aren't rusty years later. It's far more than "just two rows extra" for proper double entry with the right number of "accounts" and a lot more things form "accounts" than you think. Some of those accounts should read 0 after a proper transaction. Those become red flags if a transaction failed in the middle, and debugging tools when that happens (is it an extra credit or an extra debit, the account positive or negative/owed something or owing something, that can be very useful information to have on the failed database transaction). It seems like a lot of extra steps, but each step should also reflect your domain model in useful ways: don't create new reservations until a reservation invoice has been filled/paid for. Even in cases where you are doing direct sales to a customer and don't think you need "proper" invoices and that the transactions existing in the first place are good enough, it's still sometimes a useful domain model to have that invoice concept and rather than "fire off" events like "Create Reservation" purely on the sales transaction, have a stronger "state model" with an "Invoice Completion" step. It's an abstraction that sometimes gains you some peace of mind that you don't accidentally make a new reservation from an over-payment or a payment intended for a different purpose.