Artifact bfff70eea99198c6dfe42e61800a96d780fe12cf:

Wiki page [Dev-Compta] by bohwaz on 2018-05-23 16:42:16.
D 2018-05-23T14:42:16.763
L Dev-Compta
N text/x-markdown
U bohwaz
W 10246
# Design de la compta à double entrée dans Garradin

En compta à double entrée on reflète l'idée que l'argent n'est jamais créé ou détruit mais simplement transféré d'un compte à l'autre. « Rien ne se crée, rien ne se perd, tout se transfère ! »

## Design original (2012-2018)

Le design de stockage et gestion de la compta à double entrée adopté au début de Garradin est comme suit :

* une table compta_journal stocke les écritures, chaque écriture est une ligne dans la table, avec un montant, le numéro du compte de débit et le numéro du compte de crédit
* le solde des comptes est calculé dynamiquement en SQL quand on en a besoin
* les bilans, compte de résultat, etc. sont calculés dynamiquement
* les montants sont stockés en nombre à virgule flottante (FLOAT)

Avantages de ce design :

* Simplicité du stockage des données, simplicité de l'entrée des écritures

Problèmes avec ce design :

* Il y a eu des bugs avec des erreurs d'arrondi
* Impossible de faire une écriture complexe qui créditerait/débiterait plusieurs comptes à la fois (mais avec toujours une égalité crédit/débit de l'écriture)
* Requêtes SQL très complexes (et parfois lentes) pour obtenir des infos
* Requête SQL trop lente pour le report à nouveau

## Nouveau design (2018+)

### Fonctionnalités désirées :

* Portabilité des données depuis le design actuel
* Possibilité d'avoir plusieurs entrées (plusieurs débits/crédits sur plusieurs comptes) dans une écriture
* Amélioration des performances
* Simplification des requêtes de visualisation (amenant une amélioration des performances)
* Validation des écritures : une fois une écriture validée impossible de la modifier / supprimer mais possibilité de faire une écriture corrective (*"reversability"*)
* Possibilité d'activer une option *inaltérabilité* qui ajouterait une signature de chaîne à chaque transaction validée (écriture), voir [le ticket idoine](/tktview?name=5470b2e56b)
* Archivage des exercices précédents
* Purge des écritures des exercices clos

### Idées à confirmer :

* Utilisation d'une seule colonne pour le montant, utilisation d'un montant positif pour débiter et négatif (-) pour créditer. Devrait permettre un calcul plus simple des totaux.
* Une table compta\_comptes\_balances devrait exister et contenir le numéro du compte, le numéro de l'exercice et la balance du compte, cette balance étant mise à jour par un `TRIGGER` SQLite lors de l'ajout / modification / suppression d'une écriture, permettant d'avoir très rapidement la balance des comptes et aussi produire des résultats/bilans. Cela devrait rendre l'enregistrement d'écriture légèrement plus lent par contre (requête supplémentaire). Ça pourrait être une simple `VIEW` sinon ?

### Résolutions :

* Ajout d'une colonne *validation* dans le journal permettant de savoir si une écriture est validée ou non. Une écriture validée ne peut plus être modifiée / supprimée.
* Séparation des écritures et "sous-écritures" pour permettre d'avoir plusieurs lignes dans une écriture (mais toujours balancée débit/crédit)
* Utilisation de transactions et vérifications pour empêcher d'avoir seulement certaines des lignes de l'écriture dans la base si une des lignes échoue ! (solution : mettre un champ `enregistré` dans la table et changer sa valeur quand toutes les lignes sont ajoutées !)
* Vérification que les lignes des écritures obtiennent toujours débit = crédit !
* Stocker les montants sous forme d'entiers (INTEGER), ne pas utiliser d'opérations mathématiques pour rajouter la virgule (multiplication / division) mais simplement rajouter la virgule dans une chaîne de texte avant les deux dernières décimales

## Ressources utiles

Pour comprendre / réviser les bases de la compta :

* [Chapitre 2 : la comptabilité en partie double](http://www.comptanat.fr/privee/priv2.htm)
* Subledger: [Accounting for Developers 101](https://docs.google.com/document/d/1HDLRa6vKpclO1JtxbGB5NeAYWf8cf1UMGy22o8OZZq4/edit#)
* Subledger: [Accounting for Developers 102](https://docs.google.com/document/d/1qhtirHUzPu7Od7yX3A4kA424tjFCv5Kbi42xj49tKlw/edit)

Une bonne inspiration pour comprendre la compta en informatique c'est de regarder du côté des logiciels de compta en ligne de commande (format texte) comme [Ledger](https://www.ledger-cli.org/), [Abandon](https://github.com/hrj/abandon), [Beancount](http://furius.ca/beancount/) et [hLedger](http://hledger.org/) :

* [Plain text accounting](http://plaintextaccounting.org/) a pas mal de ressources sur le sujet
* [Syntax Quick Reference for the Ledger-Likes](http://plaintextaccounting.org/quickref/) donne de bonnes pistes pour certains problèmes courants
* [Keeping finances with Ledger](https://www.petekeen.net/keeping-finances-with-ledger) Archive: <http://archive.is/fITNv>
* [Collection of ledger-cli commands ](https://gist.github.com/agaviria/3317397) Archive: <http://archive.is/nHvwX>
* [Ledger discussion on Hacker News](https://news.ycombinator.com/item?id=10510394) Archive : <http://archive.is/ZTVaJ>
* [Ledger, a powerful CLI accounting tool (another Hacker News discussion)](https://news.ycombinator.com/item?id=7707262) Archive: <http://archive.is/RPgY1>
* [List of Ledger-inspired software](https://github.com/ledger/ledger/wiki/Ports)
* Groupe Reddit: <https://www.reddit.com/r/plaintextaccounting/>

Comme inspiration on peut aussi regarder du côté des logiciels libres faisant de la compta double entrée :

* [SQL Ledger](https://www.sql-ledger.com/) est le plus connu mais son interface est horrible et son code est peu lisible (aucun commentaire). Leur [schéma PostgreSQL](https://github.com/Tekki/sql-ledger/blob/full/sql/Pg-tables.sql) peut donner des idées… si on arrive à le comprendre.
* [GNUCash](https://www.gnucash.org/) est le plus complet probablement. Il peut faire des écritures simples ou complexes ("split") cf. [la doc](https://www.gnucash.org/docs/v3/C/gnucash-guide/txns-registers-txntypes.html). Voir aussi de bonnes infos dans le code source : [Transaction.h](https://github.com/Gnucash/gnucash/blob/maint/libgnucash/engine/Transaction.h) et [Split.h](https://github.com/Gnucash/gnucash/blob/maint/libgnucash/engine/Split.h). Ils utilisent des "transactions" qui contiennent des "splits" (ou "ledger entries"). Apparemment GNUCash permet de stocker ses données avec SQLite/mySQL et il y a donc un [schéma SQL disponible](https://wiki.gnucash.org/wiki/SQL) qui confirme ce concept de stockage. [Une discussion sur la liste](http://gnucash.1415818.n4.nabble.com/SQLite-Backend-Data-td3253474.html) explique aussi le concept de stockage des montants et du nombre de chiffres après la virgule. Leur [doc interne](https://github.com/Gnucash/gnucash/blob/maint/libgnucash/doc/design/engine.texi) est un peu vieillote mais explique un peu mieux.
* [KMyMoney](https://docs.kde.org/trunk5/en/extragear-office/kmymoney/details.database.html) semble utiliser le même modèle
* [Dolibarr](https://wiki.dolibarr.org/index.php/Table_llx_accountingdebcred) utilise une table de transactions et une table de débits/crédits, de la même manière.

Conception de base de données pour la compta à double entrée :

* [Basic double-entry bookkeeping system, for PostgreSQL](https://gist.github.com/NYKevin/9433376) donne un exemple de schéma PostgreSQL pour de la compta à double entrée, mais ça reste très basique.
* Sur StackExchange : [Double entry bookkeeping database design](https://dba.stackexchange.com/questions/102370/double-entry-bookkeeping-database-design) pose la question de stocker les écritures sous la forme de deux lignes ou une seule ligne dans une table de transactions (conclusion : utiliser une seule ligne), avec notamment la problématique de faire des débits/crédits dans plusieurs comptes dans la même écriture (la solution donnée ne résoud pas le problème)
* Sur StackExchange encore : [Should a ledger DB store a separate line for each side of a transaction?](https://dba.stackexchange.com/questions/67864/should-a-ledger-db-store-a-separate-line-for-each-side-of-a-transaction) suggère qu'il faudrait une ligne par écriture de chaque opération
* [Double Entry Accounting in a Relational Database](http://web.archive.org/web/20130415144218/http://homepages.tcp.co.uk/~m-wigley/gc_wp_ded.html) par Michael Wigley. Miroir : <https://medium.com/@RobertKhou/double-entry-accounting-in-a-relational-database-2b7838a5d7f8>
* [Database schema of double-entry accounting module](http://filipmatthew.com/technology/database-schema-of-double-entry-accounting-module/) - Archive : <http://archive.is/XxFQk> - Un exemple réel de base de données pour de la compta à double entrée, mais ne répond pas à la question de la création de bilans, comptes de résultat etc. avec ce schéma.
* [Simple Accounting database design](http://simpleaccounting.freeservers.com/database.htm) Archive : <http://archive.is/ag2DI>
* [Structuring Database for Accounting (PDF)](http://ncert.nic.in/ncerts/l/keac214.pdf)
* Le livre **Martin Fowler - Analysis Patterns - Reusable Object Models (1996)** (page 98 et suivantes) indique aussi d'utiliser des "multi-legged transactions" en fait d'avoir une table `Transaction` qui est liée par plusieurs entrées dans la table `Entry` et `Transaction` est chargé de vérifier que `SUM(Entry.amount) == 0`
* <http://www.vbforums.com/showthread.php?687131-SQL-Table-and-row-linking-Double-entry-accounts>
* Autres discussions sur StackOverflow :
	* <https://stackoverflow.com/questions/5079506/accounting-and-database-design-storing-debit-and-credit-amount> (la dernière réponse est la plus intéressante)
	* <https://stackoverflow.com/questions/4373968/database-design-calculating-the-account-balance> 
	* <https://stackoverflow.com/questions/1116823/accounting-system-design-databases>
	* <https://stackoverflow.com/questions/29688982/derived-account-balance-vs-stored-account-balance-for-a-simple-bank-account/29713230#29713230> Très intéressant !
	* <https://stackoverflow.com/questions/4074737/accounting-database-storing-a-transaction> Pareil !
Z f5fba29adfda8e4967278213ba876f78