Artifact cb892de0afc57c328f68284e0bd8aae3398d480a:

Wiki page [Dev-Compta] by bohwaz on 2019-02-20 16:09:27.
D 2019-02-20T15:09:27.081
L Dev-Compta
N text/x-markdown
P 0b89c163b3fc8ec3758217086df981dc25346347
U bohwaz
W 13191
# 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

#### Compta simplifiée

Une partie de compta simplifiée doit être présente pour permettre aux non-comptables de rentrer les opérations courantes d'une asso, cela signifie :

* Saisie d'une balance initiale
* Recettes, dépenses
* Virements entre comptes, dépôt d'espèces, retrait d'espèces
* Chèques en attente d'encaissement, dépôt de chèques
* Dettes, créances
* Contribution en nature et dons de bénévoles en nature

L'idée étant d'avoir un accès simplifié à la compta pour un non comptable, mais une progression possible (ou une utilisation hybride) vers la compta à double entrée.

Lorsqu'aucune écriture n'existe dans la compta, la page d'accueil de la compta doit proposer de choisir le plan comptable (belgee/français) puis de faire une saisie initiale.

Par défaut aucun exercice n'existe, on est sur un exercice glissant, qui doit permettre de remplir des opérations quelle que soit leur date et de générer des rapports (bilan, etc.) selon une période dynamique.

Si on crée un exercice, on doit découper les écritures existantes selon les périodes données. Ensuite il n'est plus possible d'être en exercice glissant.

Les opérations suivantes sont considérées comme accessibles aux débutants :

* Saisie simple
* Saisie simple rapide (saisie au km)
* Saisie initiale
* Gestion des comptes bancaires et caisses
* Gestion des catégories de recettes/dépenses
* Report automatisé des soldes

Fonctions avancées :

* Saisie avancée directement de compte à compte
* Rapprochement
* Validation d'écriture (avec signature)
* Ecriture corrective
* Modification du plan comptable

#### Page d'accueil compta

Liens :

* recherche
* import / export CSV/ODS
* soldes des comptes et caisses
* nombre de dettes et créances en cours (avec liens  vers leurs pages)
* nombre de chèques à déposer en banque
* nombre d'écritures à rapprocher
* graphiques d'évolution recettes/dépenses

### Lignes multiples pour une écriture :

* Deux colonnes : une pour la somme au crédit, une pour la somme au débit. Une des deux doit valoir zéro.
* Contrainte CHECK : débit * crédit == 0 et débit + crédit > 0
* Ça permettra de calculer le solde d'un compte en utilisant `SUM(debit) - SUM(credit)` ou l'inverse, selon le sens du compte
* Ajout de VIEWs pour permettre de simplifier les requêtes ?

### Idées abandonnées :

* <s>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.</s>
* <s>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 ?</s>

### 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)
* [Sens des comptes](https://www.compta-online.com/comptes-crediter-ou-debiter-t59028)
* [Liste des comptes avec leurs sens](https://thanatofrance.wordpress.com/2018/03/11/comptabilite-plan-comptable-liste-des-comptes-generaux-sens-des-comptes/)
* [Sens d'imputation comptable](https://www.compta-facile.com/imputation-comptable/)

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 !
* [Compta avec Access](https://claudeleloup.developpez.com/tutoriels/access/outil-comptable/)

Une solution de compta en ligne un peu brouillon mais intéressante : [Zefyr](https://www.zefyr.net/)
Z 81e0c8135bdc17b87dc99eef9569d17e