1. Le .ledger : un format de Grand Livre ouvert.. et simple

2014/05/01 Stand manif
	Don:Anonyme   -42
	Caisse:Grève   42

2014/05/08 Propagande
	Caisse:Grève             -7
	Achat:Impression:Tracts   7

; Répéter ad nauseam

1.1. Les plus

Transparent

Visibilité de toutes les informations.

Pérenne

Compréhensible sans peine.

Modifiable

Pas d’interface protectrice.

Accès

Pas de changement d’interface non-consenti.

Versionnable

Suivi et fusion simples des modifications.

Écrit

Langage pour s’exprimer clairement, par exemple pour discuter dans un courriel.

Hors-ligne

Pas besoin de réseau.

Interopérable

Pas spécifique à un éditeur logiciel particulier (sauf fonctionnalité expérimentale).

1.2. Les moins

Modifiable

Mais pas moins que les autres logiciels et à nuancer si couplé à un gestionnaires de versions, et/ou avec signature cryptographiques.

% git tag --sign   v2011 -m "Clôture de la comptabilité 2011"
% git tag --verify v2011
% gpg --sign         $fichier.hledger
% gpg --verify-files $fichier.hledger.gpg
Textuel

Préférable de bien savoir utiliser un éditeur de texte structuré.

Peu contraint
2102/03/21 Remise chq (1101804)
	5.Finance:1.Etablissement:1.Valeur:2.Chèque_à_encaisser  -145,00
	5.Finance:1.Etablissement:2.Banque:001.Courant            145,00
Note KISS

2. hledger : un outil libre.. et convivial

% hledger balance '^6' '^7' --depth 2 -f Paris.2011.hledger
             770,58€  6.Charge
             248,87€    0.Achat
             441,46€    1.Service
              55,25€    2.Autre_service
              25,00€    5.Gestion
            -726,00€  7.Produit
            -700,00€    0.Vente
             -26,00€    5.Autre_gestion_courante
‑-------------------
              44,58

2.1. Les plus

Utilisation
Étude
Modification
Duplication

Permises techniquement et légalement
(« logiciel libre » sous GNU/GPLv3)

Certification

Programmé en Haskell

Fonctionnel pur

Aucune mutation de données externes à une fonction (effet de bord).

Typage statique

Vérification des erreurs de type avant l’exécution du programme.

Typage fort

Aucune conversion implicite de types de données.

Portable

GNU/Linux, Apple/MacOS, Microsoft/Windows

Support

~1 développeur à mi-temps

Ligne de commande
	% hledger balance -f $fichier.hledger
Interface Web
	% hledger-web --server -f $fichier.hledger
	% firefox "http://localhost:5000"
Extensible
	% ghc hledger-fait-ce-que-je-veux.hs
	% ./hledger-fait-ce-que-je-veux -f $fichier.hledger

2.2. Les moins

Ligne de commande

3. Installer hledger

Debian/jessie
% sudo apt-get install hledger hledger-web

3.1. Via cabal

Debian/wheezy
% echo 'PATH="$HOME/.cabal/bin:$PATH"' >>~/.profile
  # NOTE: rajoute dans le chemins des exécutables
  # les exécutables installés par cabal
% exit # NOTE: recharge ~/.profile

% sudo apt-get install ghc cabal-install \
               libncurses5-dev libtinfo-dev zlib1g-dev
% cabal update
% cabal install cabal # NOTE: met à jour cabal
% cabal install happy # NOTE: anticipe une dépendance exécutable
% cabal install hledger
% cabal install alex # NOTE: anticipe une dépendance exécutable
% cabal install warp-2.0.3.4 hledger-web
  # NOTE: aide cabal à sélectionner un warp qui fonctionne
Mise-à-jour
% cabal install --reinstall hledger hledger-web

3.1.1. Version de développement

% git clone http://github.com/simonmichael/hledger.git ~/src/hledger
% cd ~/src/hledger
% cabal install --reinstall --force-reinstalls \
                ./hledger-lib ./hledger ./hledger-web

4. Écrire en .ledger

Un .ledger est un fichier de texte brut respectant une syntaxe préçise qui forme une succession d’écritures comptables, ordonnées librement.

4.1. Exemple

; Ceci est un exemple de livre comptable « ledger »
; NOTE: fantaisiste comptablement parlant, mais syntaxiquement correct

2014/01/01 Libellé de l’écriture ; UN_TAG:, Autre_tag:Avec_Valeur
	Compte:Sous-Compte                         -42 ; flux créditant
	Autre_Compte:Sous-Compte:Sous-Sous-Compte   42 ; flux débitant

2014/01/01 Deuxième écriture le même jour
	Vente:Âme  -666 ; (tag de flux) Arnaque:
	Kapital     666

2014/01/02 Troisième écriture le jour suivant avec ventilation des flux
	Compte:Crédité:A  -1
	Compte:Crédité:B  -2
	Compte:Débité:Z    1
	Compte:Débité:Y    1
	Compte:Débité:X:x  1

2014/04/12
	Compte:Crédité  -1234,56
	Compte:Débité ;  1234,56 (montant inféré)

2014/02/01 Écriture non ordonnée par date ; Ok, mais déconseillé
	Compte:Débité    1
	Compte:Crédité  -1 ; Flux non ordonné par crédit/débit
	 ; c'est juste moins lisible...

; Répéter ad nauseam

4.2. Langage

Syntaxe (grammaire BNF) Structure (signatures fonctionnelles)
livre ::= (écriture | commentaire | "⏎" | "␣")*
livre

$ :\>f:\textcolor{#D2691E}{\textbf{fichier}} → \lbrack\textcolor{#D2691E}{\textbf{\acute{e}criture}}\rbrack$

écriture ::= date "␣" "␣"* libellé commentaire "⏎"
             ("␣" flux "⏎")*
date ::= (année "/")? mois "/" jour
libellé ::= (· - (";"|"⏎"))*
date

$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → (\textcolor{#083194}{\textbf{ann\acute{e}e}}:\textcolor{#D2691E}{\textbf{ℕ}},~ \textcolor{#083194}{\textbf{mois}}:\{\textcolor{#D2691E}{\textbf{01}},...,\textcolor{#D2691E}{\textbf{12}}\},~ \textcolor{#083194}{\textbf{jour}}:\{\textcolor{#D2691E}{\textbf{01}},...,\textcolor{#D2691E}{\textbf{31}}\})$

libellé

$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → \textcolor{#D2691E}{\textbf{texte}}$

commentaire

$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → \textcolor{#D2691E}{\textbf{texte}}$

tags

$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → \lbrack\textcolor{#D2691E}{\textbf{tag}}\rbrack \ =\ \textbf{tags}~(\textbf{commentaire}~e)$

flux

$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → \lbrack\textcolor{#D2691E}{\textbf{flux}}\rbrack$

flux ::= compte "␣␣" "␣"* ("-" crédit | débit) ("␣"|"⏎")* commentaire
compte ::= nom ( ":" nom )*
nom ::= (· - (":"|"⏎")) (· - (":"|"⏎"))*
crédit ::= quantité
débit  ::= quantité
compte

$ :\>f:\textcolor{#D2691E}{\textbf{flux}} → \lbrack\textcolor{#D2691E}{\textbf{nom}}\rbrack$

montant

$ :\>f:\textcolor{#D2691E}{\textbf{flux}} → \textcolor{#D2691E}{ℚ} = \displaystyle{ \left\{\begin{array}{ll} -~(\textbf{cr\acute{e}dit}~f) & \mathit{\mbox{si défini}} \\ (\textbf{d\acute{e}bit}~f) & \mathit{\mbox{sinon}} \end{array}\right}$

tags

$ :\>f:\textcolor{#D2691E}{\textbf{flux}} → \lbrack\textcolor{#D2691E}{\textbf{tag}}\rbrack \ =\ \textbf{tags}~(\textbf{commentaire}~f)$

commentaire ::= ( ";" (tag ":" valeur? | ·)* )
     ( ("⏎"|"␣")* ";" (tag ":" valeur? | ·)* )*
tags

$ :\>m:\textcolor{#D2691E}{\textbf{commentaire}} → \lbrack\textcolor{#D2691E}{\textbf{tag}}\rbrack$

tag

$ :\>(\textcolor{#083194}{\textbf{tag}}:\textcolor{#D2691E}{\textbf{texte}},% ~\textcolor{#083194}{\textbf{valeur}}:\textcolor{#D2691E}{\textbf{\mbox{texte}}\>?})$

4.3. Calculs

compte_parent

$:\>c : \textcolor{#D2691E}{\textbf{compte}} → \textcolor{#D2691E}{\textbf{compte}}\>?$
$=\>c_{\lbrack0,\cdots,|c|-2\rbrack}\ \mbox{si}\ |c| \ge 2$

hiérarchie_de_compte

$:\>\mathbb c : \textcolor{#D2691E}{\textbf{compte}} → \lbrack\textcolor{#D2691E}{\textbf{compte}}\rbrack$
$=\>\lbrack{\ c\ :\ \lbrack{\ c\ |\ c ← (\mathbf{compte\mbox{_}parent}\>{c})}\ \rbrack}\ \rbrack$

comptes

$:\>\mathbb E : \lbrack\textcolor{#D2691E}{\textbf{\acute{e}criture}}\rbrack → \{\textcolor{#D2691E}{\textbf{compte}}\}$
$\{\ (\textbf{compte}\>f)\ |\ f ← (\textbf{flux}\>e)\ |\ e ← \mathbb E\ \}$

balance

$:\>\mathbb F : \lbrack\textcolor{#D2691E}{\textbf{flux}}\rbrack → ℚ$
$=\>{(\ m\ |\ m ← m + (\textbf{montant}\>f)\ |\ f ← \mathbb F\ |\ m ← 0\ )$

solde_de_compte

$:\>\mathbb E : \lbrack\textcolor{#D2691E}{\textbf{\acute{e}criture}}\rbrack → c : \textcolor{#D2691E}{\textbf{compte}} → ℚ$
$=\>{\textbf{balance}\>\lbrack{\ f\ |\ f ← (\textbf{flux}\>e),\ c\>≼\>(\textbf{compte}\>f)\ |\ e ← \mathbb E\ }\rbrack$

solde

$:\>\mathbb E : \lbrack\textcolor{#D2691E}{\textbf{\acute{e}criture}}\rbrack → \lbrack\textcolor{#D2691E}{\textbf{flux}}\rbrack$
$=\>\displaystyle{\left\lbrack \begin{array}{l} (\textcolor{#083194}{\textbf{compte}}=c´, \textcolor{#083194}{\textbf{montant}}=m) \\ |\ m ← (\mathbf{\mbox{solde_de_compte}}\,\mathbb E\,c´) \\ |\ c´ ← (\mathbf{hi\acute{e}rarchie\mbox{_}de\mbox{_}compte}\,c) \\ |\ c ← (\mathbf{comptes}\,\mathbb E) \end{array}}\right\rbrack$

4.4. Utiliser un éditeur de texte structuré (vim)

Coloration syntaxique sur mesure
  • hledger.vim
    ~/.vimrc
    autocmd BufNewFile,BufRead *.hledger,*.ledger setfiletype hledger
    
Complètement automatique des comptes (<Tab>)
Alignement automatique des montants

4.4.1. Suivre les modifications à plusieurs et/ou à distance (git)

TODO

5. Commandes hledger

5.1. Calculer des soldes (balance)

% hledger balance -f $fichier.ledger $filtre
Suivi des comptes
% hledger balance -b 2012/02/01 -e 2012/04/30              --monthly -f $fichier.ledger >/tmp/bal.flow
% hledger balance -b 2012/02/01 -e 2012/04/30 --cumulative --monthly -f $fichier.ledger >/tmp/bal.cumulative
% hledger balance -b 2012/02/01 -e 2012/04/30 --historical --monthly -f $fichier.ledger >/tmp/bal.historical
% gvimdiff -o /tmp/bal.{cumulative,historical}
data/gvimdiff-cumulative-historical.png

5.2. Filtrer des écritures (print)

TODO

5.3. Suivre un compte (register)

TODO

5.4. Observer des statistiques (stats, activity)

TODO

6. Exercice comptable

6.1. Plan comptable d’une association

#include::data/Cyclofficine.Plan_comptable.hledger[]

6.2. Comptabiliser en partie double

Solde nul de toute écriture
Pour toute écriture

Tout ce qui est débité (+) dans ses comptes
est forcément crédité (-) dans ses autres comptes.

  • $\forall e : \textcolor{#D2691E}{\textbf{\acute{e}criture}}, \ \textbf{balance}\>(\textbf{flux}\>{e}) = 0$
Relation de Chasles par écritures d’engagement et de paiement
01/01 Écriture d’engagement
	7.Produit:0.Vente:1.Produit_fini:1.Vélo                  -80
	5.Finance:1.Etablissement:1.Valeur:2.Chèque_à_encaisser   80

01/02 Écriture de paiement
	5.Finance:1.Etablissement:1.Valeur:2.Chèque_à_encaisser  -80
	5.Finance:1.Etablissement:2.Banque:001.Courant            80
Note pour des espèces, transiter par : 5.Finance:3.Caisse:1.Siège

6.2.1. Soldes nuls souhaitables

  • Écritures des recettes
    1. $\sum{\mbox{ventes}} + \sum{\mbox{dons}} = \sum{\mbox{espèces entrées en caisse}} + \sum{\mbox{Chèques à encaisser}}$
      (Total des ventes + dons == Total d’espèces entrée en caisse + Chèques à encaisser (5112))
    2. Total chèques à encaisser (5112) == Total remises de chèques à la banque (512) (+/- argent non déposé en banque)
    3. Solde du compte caisse (531) == Total entrées espèces en caisse - Total des sorties (remises d’espèces en banque - sorties d’achats - erreur de caisse)
    4. Solde compte caisse (531) == Total entrées en caisse - Dépôt espèce en banque - Achat en espèce
  • Écritures de paye

    TODO

6.3. Journaux (filtres)

Banque
hledger print -f $fichier.ledger '^5.Finance:1.Etablissement:2.Banque:'
Achats
hledger print -f $fichier.ledger '^(2.Immobilisation:1.Corporelle:|6.Charge:(0.Achat|1.Service|2.Autre_service):)'
Vente
hledger print -f $fichier.ledger '^7.Produit:0.Vente:'
Caisse
hledger print -f $fichier.ledger '^5.Finance:3.Caisse:'
Paye
hledger print -f $fichier.ledger '6.Charge:(3.Impôt:(1.|3.):|4.Personnel:)'
À NouVeaux
hledger print -f $fichier.ledger tag:ANV
Opération_Diverses
hledger print -f $fichier.ledger tag:OD

6.4. Clôture / Ouverture (equity)

hledger-equity calcule une balance de comptes et en fait deux écritures, respectivement :

de clôture

pour les solder à zéro en fin d’exercice ;

d’ouverture

pour les réinitialiser à leur solde du précédent exercice.

% hledger-equity -f $fichier.ledger $filtre
Solde des compte de gestion
% hledger-equity '^6' '^7' -f Paris.2011.hledger
2014/07/29
    6.Charge:0.Achat:6.Non_stocké:8.Autre_Matière,Fourniture:1.Atelier      -248,87
    6.Charge:1.Service:3.Location:2.Immobilière                             -441,46
    6.Charge:2.Autre_service:3.Communication:6.Catalogue,Imprimé             -24,00
    6.Charge:2.Autre_service:7.Service_bancaire                              -31,25
    6.Charge:5.Gestion:8.Divers:6.Cotisation_(vie_statutaire)                -25,00
    7.Produit:0.Vente:6.Prest'action                                         700,00
    7.Produit:5.Autre_gestion_courante:6.Cotisation                           20,00
    7.Produit:5.Autre_gestion_courante:8.Divers                                6,00
    equity:closing balances                                                   44,58

2014/07/29
    6.Charge:0.Achat:6.Non_stocké:8.Autre_Matière,Fourniture:1.Atelier       248,87
    6.Charge:1.Service:3.Location:2.Immobilière                              441,46
    6.Charge:2.Autre_service:3.Communication:6.Catalogue,Imprimé              24,00
    6.Charge:2.Autre_service:7.Service_bancaire                               31,25
    6.Charge:5.Gestion:8.Divers:6.Cotisation_(vie_statutaire)                 25,00
    7.Produit:0.Vente:6.Prest'action                                        -700,00
    7.Produit:5.Autre_gestion_courante:6.Cotisation                          -20,00
    7.Produit:5.Autre_gestion_courante:8.Divers                               -6,00
    equity:opening balances                                                  -44,58

7. Import et export avec hledger

7.1. Feuilles de calculs des documents comptables

7.1.1. Bilan financier

TODO

7.1.2. Comptes de résultats

TODO

8. hledger-web

TODO

9. (bonus) Scripter hledger

TODO

9.1. Installer un script hledger

% echo 'PATH="$HOME/src/hledger/extra:$PATH"' >>~/.profile
% exit # NOTE: recharge ~/.profile
% ghc ~/src/hledger/extra/hledger-SCRIPT.hs

10. Communauté

hledgersplash