If you will be ever considering an idea to build double-entry accounting functionality in your project by your own, I have one simple thing to say: don’t do it. It’s complex, uneasy and risky. I suggest to take a look on Subledger project. Do you want to do it anyway? Okay.
Subldeger is great API to enrich your existing application by double-entry accounting functionality via simple REST API. They also offer very interesting way of pricing (based on account moves). My problem was that I expected much more complex functionality on collected data which Subledger unfortunately didn’t offered.
The first problem I have met during my development was a creation of data model. I had several hours of talks with my CFO and even I have never had a problem of modeling any complex use case, this was something a little different. I need to admit the double-entry accounting field was something very new for me that time.
I was researching over open-source projects and was trying to learn their ways of solution. But the resources were limited. After all the investigation, studying, modeling and testing I figured out the following data model which succeeded in covering all the required features. And it can be used as a study material for any other developer working on the same anytime in future. Like I read somewhere: double-entry accounting was found 600 years ago and didn’t changed significantly until now.
This is not a fully functional database model but can help at least to visualise the structure.
The most important model in double-entry accounting is account. Accounts can be related to sales, stocks, taxes, bank accounts or anything other. The mystery of accounting is hidden in a well designed chart of accounts which is typically made by accountant. There are international standards but every company can add more accounts for a better overview of it’s business. Every account keeps a actual amount of debit & credit (these are updated with every new move related to particular account).
When new invoice, purchase, refund or payment is created in the system, new move is created. The move holds information about reference (which entity produced this move), relation to partner/customer and date when move was created.
Then move consist of several move_line(s) entries. And here is the magic. Every line keeps information of amount which was debited or credited to particular account. All lines under one move needs to be balanced. This means that all debits and credits needs to be counted to zero (better said: the same amount credited from one account have to be debited to another one(s)). Typically one invoice can produce unspecified number of lines (amount to be paid by customer, tax to be collected, sales amount per every product, etc.)
This is a very simple example of just three core models of double-entry accounting. But in real application, the architecture gets much more complicated with a need to involve fiscal years, accounting periods, journals(books), etc.
For more information I suggest to read Accounting for Developers.