[HN Gopher] Accounting for developers part III - building a lend...
       ___________________________________________________________________
        
       Accounting for developers part III - building a lending marketplace
        
       Author : mattmcf
       Score  : 130 points
       Date   : 2022-10-20 13:17 UTC (9 hours ago)
        
 (HTM) web link (www.moderntreasury.com)
 (TXT) w3m dump (www.moderntreasury.com)
        
       | cosmiccatnap wrote:
       | Would love to see development for accountants so everytime
       | marketing needs a new tool integrated to run a report they can
       | see the time it takes to provision, implement, test, release, and
       | then audit it.
        
       | GGO wrote:
       | Modern Treasury blogs are always full of gold nuggets. Is there
       | RSS feed for this?
        
         | EliasLittle wrote:
         | yep! https://www.moderntreasury.com/journal/rss.xml
         | 
         | You can also get automatic emails
        
       | [deleted]
        
       | danielrhodes wrote:
       | Having contributed to a project that needed to apply these
       | principles in a previous role, it can't be understated how
       | important it is to understand these concepts.
       | 
       | One thing I found interesting though is that one feature of
       | double entry accounting is creating a paper trail where some lost
       | data can be reconstructed if necessary with redundancies. For
       | example if you lose the physical pages detailing a transaction,
       | you can figure out what happened based on data contained in
       | another page. A problem we ran into was how to reconcile that
       | methodology with how this would be solved in code (e.g. DB
       | backups).
        
         | DimitriPetrova wrote:
         | You should take a look at SAP's source code
        
       | skipants wrote:
       | I still don't understand why they encourage double-entry
       | accounting for tech. In my experience entries like:
       | 
       | | amount | payer_id | payee_id |
       | 
       | | 100 | 1 | 2 |
       | 
       | are more than sufficient. He uses Square, Uber, and Airbnb as
       | examples in https://www.moderntreasury.com/journal/accounting-
       | for-develo... but, as far as I can tell, only Square uses double-
       | entry.
       | 
       | Double entry accounting was for when people were hand-writing a
       | ledger and it helped avoid mistakes. It makes no sense in code
       | and it just makes your DB queries more complicated.
        
         | zie wrote:
         | What happens if you need to split that $100 from payer_id 1
         | into 2 payer_id 2's?
         | 
         | I.e. that $100 is actually:
         | 
         | $99 from 1 to 2 and $1(let's say in taxes) to payer_id 3.
         | 
         | The easy answer is, make it 2 transaction, $99 to 2 and $1 to
         | 3, but then you can't tell that the $1 in taxes is from the $99
         | transaction. That leads to headaches when you need to balance
         | your taxes.
        
           | skipants wrote:
           | This is just the ledger table. In your case you would have a
           | payment event table with one row and a join table that
           | connects that event with all the ledger rows.
           | 
           | That's what Airbnb seems to do: https://medium.com/airbnb-
           | engineering/tracking-the-money-sca...
        
             | zie wrote:
             | Or just go full double entry and allow multiple accounts
             | per transaction, which is what anyone with an accounting
             | degree would tell you to do.
             | 
             | The bonus of doing it this way, everyone with an accounting
             | degree won't gasp in horror when they understand what it is
             | you did.
             | 
             | The events table in your example is basically the same as a
             | transaction table and dump the transaction_id into the
             | ledger table. The bonus of doing it with a 'transaction_id'
             | is accountants, auditors and the rest won't be confused.
        
         | 2Gkashmiri wrote:
         | what do you mean dont use double entry and use a DB query
         | instead?
         | 
         | if your customer is paying you, how will you record that
         | transaction?
        
         | WorldMaker wrote:
         | 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 wrote:
           | Not 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 wrote:
             | You 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.
        
         | helsontaveras18 wrote:
         | We've built our own in house ledger and also use double entry
         | accounting. When one transaction affects multiple accounts, you
         | need to ensure the books balance, which the premise of double
         | entry accounting.
         | 
         | It's the standard for a reason. Even when using a software like
         | Quickbooks, errors can come up.
        
         | thfuran wrote:
         | Isn't your example double entry? It shows both accounts
         | involved in the transaction and the direction of the
         | transaction.
        
           | skipants wrote:
           | Double-entry is recording the credits and debits in a column
           | and each account change happens on a row.
           | 
           | So if I change the ledger in my parent comment to double
           | entry it would look like:
           | 
           | | account_id | credit_amount | debit_amount |
           | 
           | | 1 | 0 | 100 |
           | 
           | | 2 | 100 | 0 |
        
       ___________________________________________________________________
       (page generated 2022-10-20 23:01 UTC)