= Informatiser une comptabilité avec confiance :author: git://git.cyclocoop.org/tool/hledger :copyright: © 2014 (CC) BY Julien Moutinho <julm+hledger@autogeree.net> :icons: :iconsdir: ./icons :numbered: :toc: :slidebackground: hledgersplash :slidefontsizeadjust: -3 :incremental: :revremark: :scriptsdir: $PWD/javascripts :data-uri: //:max-width: 45em ifdef::backend-slidy2[:slidebackground!:] // a2x: --xsltproc-opts "--stringparam ulink.show 1" // a2x: --xsltproc-opts "--stringparam ulink.footnotes 1" // :source-highlighter: vim == Le ++.ledger++ : un format de journal comptable ouvert.. et simple [source,hledger] ---- 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 ---- [cols="a,a"] |================================== | [float] Les plus ~~~~~~~~ [horizontal] Transparent:: Visibilité de *toutes* les informations. Pérenne:: Compréhensible sans logiciel particulier pour l’exploiter. Modifiable:: Pas de verrou (plus ou moins illusoire) de validation. Accès:: Pas de changement d’interface non-consenti. Versionnable:: Suivi des modifications, fusion des contributions, et sauvegarde simples. Écrit:: Langage pour s’exprimer clairement (par ex. dans un courriel ou une présentation). Hors-ligne:: Pas besoin de réseau. Interopérable:: Pas spécifique à un éditeur logiciel particulier (sauf fonctionnalité expérimentale). [horizontal] ledger;; http://ledger-cli.org/[] hledger;; http://hledger.org/[] beancount;; http://furius.ca/beancount/[] penny;; https://massysett.github.io/penny/[] abandon;; https://github.com/hrj/abandon/[] | [float] Les moins ~~~~~~~~~ [horizontal] Modifiable:: Mais, comme c'est un fichier, un véritable verrou validant + peut être mis par une **signature cryptographique**. + [source,sh] ---- % gpg --detach-sign $fichier.ledger % gpg --verify $fichier.ledger.sig ---- Textuel:: Préférable de ne pas avoir peur des caractères, voire de bien savoir utiliser un éditeur de texte structuré. Contrainte minimale:: « __N'a pas été conçu pour empêcher ses utilisateurs de commettre des actes stupides, car cela les empêcherait aussi de réaliser des actes ingénieux.__ » + [source,hledger] ---- 2102/03/21 Chèque ; Date suspecte 5.Finance:1.Etablissement:1.Valeur:2.Chèque_à_encaisser -145,00 5.Finance:1.Etablissement:2.Banque:001.Courant 145,00 ---- + NOTE: Mais possibilité de vérifications d’invariants conventionnels avec des scripts. |================================== == ++hledger++ : un outil libre.. et convivial [source,sh] ---- % 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€ ---- [cols="a,a"] |================================== | [float] Les plus ~~~~~~~~ Philosophie Unix:: + * « __Écrivez des programmes qui effectuent une seule chose et qui le font bien.__ » * « __Écrivez des programmes qui collaborent.__ » * « __Écrivez des programmes pour gérer des flux de texte, + car c'est une interface universelle.__ » Utilisation, Étude, Modification, Duplication:: Permises techniquement et légalement + (« logiciel libre » sous ++GNU/GPLv3++) Rigueur:: Programmé en http://fr.wikipedia.org/wiki/Haskell[Haskell] [horizontal] Fonctionnel pur;; Aucune mutation de données externes à une fonction (sans 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. Relisible:: ≈13 000 lignes de Haskell (ou 160 écrans de 80 lignes) + (plus ≈1 800 lignes pour ++hledger-web++). + NOTE: À équivalence fonctionnelle, OpenERPv7 ≈80 000 lignes de Python (≈1 000 écrans). Ancienneté:: Depuis 2007 (≈7 ans). Portable:: GNU/Linux, Apple/MacOS, Microsoft/Windows [horizontal] Ligne de commande:: Contrôle l’ordinateur avec le langage. + [source,sh] ---- % hledger add -f $fichier.hledger % hledger balance -f $fichier.hledger ---- Interface Web:: + [source,sh] ---- % hledger-web --server -f $fichier.hledger % firefox "http://localhost:5000" ---- Support:: ≈1 développeur à mi-temps-libéré + * Simon Michael (sm) + NOTE: Dons @ https://www.gittip.com/simonmichael/[] + [horizontal] Messagerie instantanée;; Liste de discussion;; Extensible:: + [source,sh] ---- % ghc hledger-fait-ce-que-je-veux.hs % ./hledger-fait-ce-que-je-veux -f $fichier.hledger ---- | [float] Les moins ~~~~~~~~~ Pas tout en un:: Fait de la comptabilité, **et juste** de la comptabilité ; pas un logiciel intégré type ERP (Enterprise Resource Planning) du genre https://www.odoo.com/[Odoo] (anciennement « OpenERP ») : Comptabilité + Point de vente + Facturation + Paye + Gestion de stock + Adhésion + Calendrier + Wiki + ... En ligne de commande:: Peur **irrationnelle** mais fréquente, d’être libre et d’avoir le pouvoir sur la machine, au lieu d’être captif d’une interface. + NOTE: L’interface Web est simple, et s’améliore. Read The Fucking Manual:: De même que maîtriser un plan comptable néçessite en plus de le parcourir de **s’informer** sur son utilisation, + de même maîtriser un langage et un logiciel en ligne de commande nécessite de **s’informer** sur sa syntaxe, sa sémantique et son utilisation. + NOTE: http://hledger.org/manual/[]. |================================== == Langage d’un fichier +.ledger+ Un +.ledger+ est un fichier de texte brut respectant une syntaxe préçise qui forme une succession d’écritures comptables, classées librement. ifdef::backend-slidy2[>>>] === Définition informelle [source,hledger] .Fichier ++data/exemple-syntaxe.ledger++ ---- include::data/exemple-syntaxe.ledger[] ---- .Conventions usuelles * Classement des écritures par date. * Classement des flux par signe, puis compte. === Définition formelle [cols="a,a",options="header"] |================================== ^|Syntaxe (grammaire https://fr.wikipedia.org/wiki/Forme_de_Backus-Naur[BNF]) ^|Informations (signatures fonctionnelles) | [source,conf] ----------------------------------- journal ::= (écriture \| commentaire \| "⏎" \| "␣")* ----------------------------------- | [horizontal] :role: math **journal**:: latexmath:[$ :\>f:\textcolor{#D2691E}{\textbf{fichier}} → \lbrack\textcolor{#D2691E}{\textbf{\acute{e}criture}}\rbrack$] | [source,conf] ---- écriture ::= date "␣" "␣"* libellé commentaire "⏎" ("␣" flux "⏎")* date ::= (année "/")? mois "/" jour libellé ::= (· - (";"\|"⏎"))* ---- | [horizontal] :role: math **date**:: latexmath:[$ :\>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é**:: latexmath:[$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → \textcolor{#D2691E}{\textbf{texte}}$] **commentaire**:: latexmath:[$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → \textcolor{#D2691E}{\textbf{texte}}$] **tags**:: latexmath:[$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → \lbrack\textcolor{#D2691E}{\textbf{tag}}\rbrack \ =\ \textbf{tags}~(\textbf{commentaire}~e)$] **flux**:: latexmath:[$ :\>e:\textcolor{#D2691E}{\textbf{\acute{e}criture}} → \lbrack\textcolor{#D2691E}{\textbf{flux}}\rbrack$] | [source,conf] ---- flux ::= compte "␣␣" "␣"* ("-" crédit \| débit) ("␣"\|"⏎")* commentaire compte ::= nom ( ":" nom )* nom ::= (· - (":"\|"⏎")) (· - (":"\|"⏎"))* crédit ::= quantité débit ::= quantité ---- | [horizontal] :role: math **compte**:: latexmath:[$ :\>f:\textcolor{#D2691E}{\textbf{flux}} → \lbrack\textcolor{#D2691E}{\textbf{nom}}\rbrack$] **montant**:: latexmath:[$ :\>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**:: latexmath:[$ :\>f:\textcolor{#D2691E}{\textbf{flux}} → \lbrack\textcolor{#D2691E}{\textbf{tag}}\rbrack \ =\ \textbf{tags}~(\textbf{commentaire}~f)$] | [source,conf] ---- commentaire ::= ( ";" (tag ":" valeur? \| ·)* ) ( ("⏎"\|"␣")* ";" (tag ":" valeur? \| ·)* )* ---- | [horizontal] :role: math **tags**:: latexmath:[$ :\>m:\textcolor{#D2691E}{\textbf{commentaire}} → \lbrack\textcolor{#D2691E}{\textbf{tag}}\rbrack$] **tag**:: latexmath:[$ :\>(\textcolor{#083194}{\textbf{tag}}:\textcolor{#D2691E}{\textbf{texte}},% ~\textcolor{#083194}{\textbf{valeur}}:\textcolor{#D2691E}{\textbf{\mbox{texte}}\>?})$] |================================== == Commandes `hledger` [source,sh] .Syntaxe quasiment commune à toutes les commandes ++hledger++ ---- % hledger $commande $options $filtre -f $fichier.ledger ---- ifdef::backend-slidy2[>>>] === Afficher le plan comptable (`accounts`) [cols="a,a"] |================================== | [float] [source,sh] ---- % hledger accounts --tree -f data/exemple-syntaxe.ledger sys::[hledger accounts --tree -f data/exemple-syntaxe.ledger] ---- [source,sh] ---- % hledger accounts --flat -f data/exemple-syntaxe.ledger sys::[hledger accounts --flat -f data/exemple-syntaxe.ledger] ---- [source,sh] ---- % hledger accounts --tree '^A' -f data/exemple-syntaxe.ledger sys::[hledger accounts --tree '^A' -f data/exemple-syntaxe.ledger] ---- | [float] **comptes**:: latexmath:[$:\>\mathbb E : \lbrack\textcolor{#D2691E}{\textbf{\acute{e}criture}}\rbrack → \{\textcolor{#D2691E}{\textbf{compte}}\}$] + = « __ensemble des comptes vers lesquels fluent les écritures__ » + latexmath:[$=\{\ (\textbf{compte}\>f)\ \|\ f ← (\textbf{flux}\>e)\ \|\ e ← \mathbb E\ \}$] **compte_parent**:: latexmath:[$:\>c : \textcolor{#D2691E}{\textbf{compte}} → \textcolor{#D2691E}{\textbf{compte}}\>?$] + = « __plus long compte strictement préfixe d’un compte__ » + latexmath:[$=\>c_{\lbrack0,\cdots,\|c\|-2\rbrack}\ \mbox{si}\ \|c\| \ge 2$] **hiérachie_de_compte**:: latexmath:[$:\>\mathbb c : \textcolor{#D2691E}{\textbf{compte}} → \lbrack\textcolor{#D2691E}{\textbf{compte}}\rbrack$] + = « __liste des comptes préfixes d’un compte__ » + // = « __ensemble des comptes vers lesquels fluent les écritures et leur comptes parents__ » + latexmath:[$=\>\lbrack{\ c\ :\ \lbrack{\ c\ \|\ c ← (\mathbf{compte\mbox{_}parent}\>{c})}\ \rbrack}\ \rbrack$] |================================== === Filtrer des écritures (`print`) ++hledger++ permet de filtrer les écritures selon leurs données (date, libellé, comptes, montants, tags, ...) ; des expressions rationnelles peuvent être utilisées à cette fin. NOTE: Cf. manuel : http://hledger.org/manual#query-arguments[] [source,hledger] ---- % hledger print 'A' -f data/exemple-syntaxe.ledger sys::[hledger print 'A' -f data/exemple-syntaxe.ledger] ---- [source,hledger] ---- % hledger print '^A' -f data/exemple-syntaxe.ledger sys::[hledger print '^A' -f data/exemple-syntaxe.ledger] ---- [source,hledger] ---- % hledger print '^B$' -f data/exemple-syntaxe.ledger sys::[hledger print '^B$' -f data/exemple-syntaxe.ledger] ---- [horizontal] .Afficher des « journaux auxiliaires » (exemples approximatifs) **Banque**:: + [source,sh] ---- hledger print -f $fichier.ledger '^5.Finance:1.Etablissement:2.Banque:' ---- **Achats**:: + [source,sh] ---- hledger print -f $fichier.ledger '^(2.Immobilisation:1.Corporelle:|6.Charge:(0.Achat|1.Service|2.Autre_service):)' ---- **Vente**:: + [source,sh] ---- hledger print -f $fichier.ledger '^7.Produit:0.Vente:' ---- **Caisse**:: + [source,sh] ---- hledger print -f $fichier.ledger '^5.Finance:3.Caisse:' ---- **Paye**:: + [source,sh] ---- hledger print -f $fichier.ledger '6.Charge:(3.Impôt:(1.|3.):|4.Personnel:)' ---- **À nouveau**:: + [source,sh] ---- hledger print -f $fichier.ledger tag:ANV ---- **Opération_Diverses**:: + [source,sh] ---- hledger print -f $fichier.ledger tag:OD ---- === Calculer des soldes (`balance`) [cols="a,a"] |================================== | [float] [source,sh] .Balance de toutes les écritures ---- % hledger balance -f data/exemple-syntaxe.ledger sys::[hledger balance -f data/exemple-syntaxe.ledger | sed -e 's/^-/‑/'] ---- NOTE: Toutes les écritures devant avoir leur balance nulle, cette balance sur toutes les écritures est également nulle. [source,sh] .Balance sur des comptes filtrés par expression rationnelle ---- % hledger balance 'A' -f data/exemple-syntaxe.ledger sys::[hledger balance 'A' -f data/exemple-syntaxe.ledger | sed -e 's/^-/‑/'] ---- [source,sh] .Balance sur un compte racine ---- % hledger balance '^A' -f data/exemple-syntaxe.ledger sys::[hledger balance '^A' -f data/exemple-syntaxe.ledger | sed -e 's/^-/‑/'] ---- [source,sh] .Sans accumulation des soldes d’une période à l’autre ---- % hledger balance --daily -f data/exemple-syntaxe.ledger sys::[hledger balance --daily -f data/exemple-syntaxe.ledger | sed -e 's/^-/‑/;s/[|]/\\|/g'] ---- [source,sh] .Avec accumulation des soldes d’une période à l’autre ---- % hledger balance --daily --historical -f data/exemple-syntaxe.ledger sys::[hledger balance --daily --historical -f data/exemple-syntaxe.ledger | sed -e 's/^-/‑/;s/[|]/\\|/g'] ---- //[source,sh] //.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} //---- //image::data/gvimdiff-cumulative-historical.png[] | [float] [horizontal] **balance**:: latexmath:[$:\>\mathbb F : \lbrack\textcolor{#D2691E}{\textbf{flux}}\rbrack → ℚ$] + = « __somme des montants des flux__ » + latexmath:[$=\>{(\ m\ \|\ m ← m + (\textbf{montant}\>f)\ \|\ f ← \mathbb F\ \|\ m ← 0\ )$] + **solde_de_compte**:: latexmath:[$:\>\mathbb E : \lbrack\textcolor{#D2691E}{\textbf{\acute{e}criture}}\rbrack → c : \textcolor{#D2691E}{\textbf{compte}} → ℚ$] + latexmath:[$=\>{\textbf{balance}\>\lbrack{\ f\ \|\ f ← (\textbf{flux}\>e),\ c\>≼\>(\textbf{compte}\>f)\ \|\ e ← \mathbb E\ }\rbrack$] + // latexmath:[$=\>{\displaystyle{\sum_{e ← \mathbb E}}\left(\sum_{\stackrel{f ← (\textbf{flux}\>e),}{c\ ≼\ (\textbf{compte}\>f)}}(\textbf{montant}\>f})\right)$] **solde**:: latexmath:[$:\>\mathbb E : \lbrack\textcolor{#D2691E}{\textbf{\acute{e}criture}}\rbrack → \lbrack\textcolor{#D2691E}{\textbf{flux}}\rbrack$] + latexmath:[$=\>\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$] |================================== Balance nulle de toute écriture:: ++hledger++ n’accepte aucune écriture qui ne respecte pas cette contrainte de la tâche comptable : + + « __Pour toute écriture, tout ce qui est [black]_débité_ (+++++) dans ses comptes + est forcément [black]_crédité_ (++-++) dans ses autres comptes, + et réciproquement.__ » + * Formellement : latexmath:[$\forall e : \textcolor{#D2691E}{\textbf{\acute{e}criture}}, \ \textbf{balance}\>(\textbf{flux}\>{e}) = 0$] + [source,hledger] ---- 2014/04/12 Compte:Crédité -1234,56 Compte:Débité ; 1234,56 (montant inféré) ---- === Calculer les écritures de clôture et ouverture (`equity`) ++hledger-equity++ est du sucre syntaxique autour de ++hledger balance++, il calcule une balance de soldes de comptes et en fait deux écritures aux montants opposés, respectivement : [horizontal] 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. [cols="a,a"] |================================== | [float] [source,sh] ---- % hledger-equity -f data/exemple-syntaxe.ledger sys::[.../script/hledger-equity -f data/exemple-syntaxe.ledger] ---- [source,sh] ---- % hledger-equity -f data/exemple-syntaxe.ledger '^A' sys::[.../script/hledger-equity -f data/exemple-syntaxe.ledger '^A'] ---- [source,sh] ---- % hledger-equity -f data/exemple-syntaxe.ledger '^B' sys::[.../script/hledger-equity -f data/exemple-syntaxe.ledger '^B'] ---- | [float] [source,sh] .Solde des comptes de gestion et calcul du compte de résultat ---- % hledger balance --flat '^6' '^7' -f Paris.2011.hledger 248,87€ 6.Charge:0.Achat:6.Non_stocké:8.Autre_Matière,Fourniture:1.Atelier 441,46€ 6.Charge:1.Service:3.Location:2.Immobilière 24,00€ 6.Charge:2.Autre_service:3.Communication:6.Catalogue,Imprimé 31,25€ 6.Charge:2.Autre_service:7.Service_bancaire 25,00€ 6.Charge:5.Gestion:8.Divers:6.Cotisation_(vie_statutaire) -700,00€ 7.Produit:0.Vente:6.Prest’action -20,00€ 7.Produit:5.Autre_gestion_courante:6.Cotisation -6,00€ 7.Produit:5.Autre_gestion_courante:8.Divers ‑------------------- 44,58€ # <-- Résultat déficitaire de 44,58€ ---- [source,hledger] .La même chose mais au format ++.ledger++ ---- % 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€ ---- |================================== === Suivre un compte (`register`) [source,sh] .Suivi de la somme des crédits du compte `5112` ---- % hledger register -f Paris.2011.hledger 'amt:<0' '^5.Finance:1.Etablissement:1.Valeur:2.Chèque_à_encaisser' 2011/05/23 Remise chq 0994029 ..Chèque_à_encaisser -100,00€ -100,00€ 2011/09/29 Remise chq 1101801 ..Chèque_à_encaisser -20,00€ -120,00€ 2011/11/18 Remise chq 1101802 ..Chèque_à_encaisser -2000,00€ -2120,00€ ---- [source,sh] .Suivi de la somme des débits du compte `5112` ---- % hledger register -f Paris.2011.hledger 'amt:>0' '^5.Finance:1.Etablissement:1.Valeur:2.Chèque_à_encaisser' 2011/05/15 Prêt ..Chèque_à_encaisser 100,00€ 100,00€ 2011/09/20 Cotisations ..Chèque_à_encaisser 20,00€ 120,00€ 2011/11/10 Prêt ..Chèque_à_encaisser 2000,00€ 2120,00€ ---- NOTE: Si ces deux commandes ne donnent pas le même montant final c’est qu’il reste des chèques à encaisser. === Observer des statistiques (`stats`, `activity`) [cols="a,a"] |================================== | [float] [source,sh] .Statistiques annuelles ---- % hledger stats --period yearly -f Paris.2012.hledger Main journal file : Paris.2012.hledger Included journal files : Paris.Plan_comptable.hledger Cyclofficine.Plan_comptable.hledger Transactions span : 2012-01-01 to 2013-01-01 (366 days) Last transaction : 2012-12-31 (576 days ago) Transactions : 210 (0.6 per day) Transactions last 30 days: 0 (0.0 per day) Transactions last 7 days : 0 (0.0 per day) Payees/descriptions : 144 Accounts : 448 (depth 6) Commodities : 1 (€) ---- | [float] [source,sh] .Jours de l’année avec au moins 5 flux ---- hledger activity --period daily -f Paris.2012.hledger \| grep '\*\{5\}' 2012-01-01 *********** 2012-02-29 ****** 2012-03-23 ****** 2012-03-31 ********* 2012-04-03 ****** 2012-04-30 ******** 2012-05-03 **************** 2012-05-11 ******** 2012-05-14 **************** 2012-05-31 ********** 2012-06-11 ****************** 2012-06-30 ************* 2012-07-13 ********* 2012-07-17 ****** 2012-07-30 ****** 2012-07-31 *********** 2012-08-31 ****** 2012-09-26 ******** 2012-09-30 ****** 2012-11-13 ******** 2012-11-30 ***** 2012-12-31 ************* ---- |================================== === Écrire des écritures (`add`) [source,sh] .Sélection d’un modèle selon le libellé ---- % hledger add -f /tmp/test.ledger Adding transactions to journal file /tmp/test.ledger Any command line arguments will be used as defaults. Use tab key to complete, readline keys to edit, enter to accept defaults. An optional (CODE) may follow transaction dates. An optional ; COMMENT may follow descriptions or amounts. If you make a mistake, enter < at any prompt to restart the transaction. To end a transaction, enter . when prompted. To quit, enter . at a date prompt or press control-d or control-c. Date [2014/07/30]: 2014/01/01 Description: Libellé de l’écriture ; UN_TAG:, Autre_tag:Avec_Valeur Account 1: A:AA Amount 1: -42 Account 2: B:BB:BBB Amount 2 [42.0]: 40 Account 3: B:A Amount 3 [2.0]: Account 4 (or . or enter to finish this transaction): . 2014/01/01 Libellé de l’écriture ; UN_TAG:, Autre_tag:Avec_Valeur A:AA -42 B:BB:BBB 40 B:A 2.0 Save this transaction to the journal ? [y]: y Saved. Starting the next transaction (. or ctrl-D/ctrl-C to quit) Date [2014/01/01]: Description: Libellé d’une autre écriture Using this similar transaction for defaults: 2014/01/01 Libellé de l’écriture ; UN_TAG:, Autre_tag:Avec_Valeur A:AA -42 B:BB:BBB 40 B:A 2.0 Account 1 [A:AA]: Amount 1 [-42.0]: 100 Account 2 [B:BB:BBB]: B Amount 2 [-100.0]: Account 3 (or . to finish this transaction) [B:A]: . 2014/01/01 Libellé d’une autre écriture A:AA 100 B -100.0 Save this transaction to the journal ? [y]: y Saved. Starting the next transaction (. or ctrl-D/ctrl-C to quit) Date [2014/01/01]: . ---- [source,sh] .Complètement automatique des comptes ---- % hledger add -f data/exemple-plan-comptable.ledger Adding transactions to journal file /home/julm/admin/cyber.coop/src/tool/hledger/doc/data/exemple-plan-comptable.ledger Any command line arguments will be used as defaults. Use tab key to complete, readline keys to edit, enter to accept defaults. An optional (CODE) may follow transaction dates. An optional ; COMMENT may follow descriptions or amounts. If you make a mistake, enter < at any prompt to restart the transaction. To end a transaction, enter . when prompted. To quit, enter . at a date prompt or press control-d or control-c. Date [2014/07/30]: yesterday Description: Trololo Account 1: 1.Capital: 1.Capital:0.Fonds 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement 1.Capital:0.Fonds:2.SDR 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement:1.État 1.Capital:0.Fonds:2.SDR:4.Apport 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement:2.Région 1.Capital:0.Fonds:2.SDR:6.Sub_invest_BR 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement:3.Département 1.Capital:0.Fonds:3.ADR 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement:4.Commune 1.Capital:0.Fonds:3.ADR:4.Apport 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement:5.Collectivité_publique 1.Capital:0.Fonds:3.ADR:6.Sub_invest_BR 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement:6.Entreprise_publique 1.Capital:0.Fonds:6.Réserve 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement:7.Organisme_privé 1.Capital:0.Fonds:6.Réserve:3.Statutaire 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:1.Equipement:8.Autre 1.Capital:0.Fonds:6.Réserve:8.Autre 1.Capital:3.Sub_invest_BNR:9.Compte_résultat:2.Autre 1.Capital:1.Report 1.Capital:5.Provision_risque&charge 1.Capital:1.Report:0.Bénéfice 1.Capital:5.Provision_risque&charge:1.Risque 1.Capital:1.Report:5.Financeur 1.Capital:5.Provision_risque&charge:5.Impôt 1.Capital:1.Report:9.Déficit 1.Capital:5.Provision_risque&charge:8.Autre 1.Capital:2.Résultat 1.Capital:5.Provision_risque&charge:8.Autre:2.Congés_à_payer 1.Capital:2.Résultat:0.Bénéfice 1.Capital:6.Emprunt,Dette 1.Capital:2.Résultat:9.Déficit 1.Capital:6.Emprunt,Dette:4.Etablissement_crédit 1.Capital:3.Sub_invest_BNR 1.Capital:6.Emprunt,Dette:5.Dépôt,Caution 1.Capital:3.Sub_invest_BNR:1.Equipement 1.Capital:6.Emprunt,Dette:8.Autre 1.Capital:3.Sub_invest_BNR:1.Equipement:1.État 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt 1.Capital:3.Sub_invest_BNR:1.Equipement:2.Région 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt:1.Bénévole 1.Capital:3.Sub_invest_BNR:1.Equipement:3.Département 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt:2.Salarié-e 1.Capital:3.Sub_invest_BNR:1.Equipement:4.Commune 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt:3.Cyclofficine 1.Capital:3.Sub_invest_BNR:1.Equipement:5.Collectivité_publique 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt:4.Autre 1.Capital:3.Sub_invest_BNR:1.Equipement:6.Entreprise_publique 1.Capital:6.Emprunt,Dette:8.Autre:7.Dette 1.Capital:3.Sub_invest_BNR:1.Equipement:7.Organisme_privé 1.Capital:9.Fonds_dédiés 1.Capital:3.Sub_invest_BNR:1.Equipement:8.Autre 1.Capital:9.Fonds_dédiés:4.Sub_exploit 1.Capital:3.Sub_invest_BNR:8.Autre 1.Capital:9.Fonds_dédiés:5.Don_affecté 1.Capital:3.Sub_invest_BNR:9.Compte_résultat Account 1: 1.Capital:6.Emprunt,Dette 1.Capital:6.Emprunt,Dette 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt:4.Autre 1.Capital:6.Emprunt,Dette:4.Etablissement_crédit 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt:1.Bénévole 1.Capital:6.Emprunt,Dette:8.Autre:7.Dette 1.Capital:6.Emprunt,Dette:5.Dépôt,Caution 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt:2.Salarié-e 1.Capital:6.Emprunt,Dette:8.Autre 1.Capital:6.Emprunt,Dette:8.Autre:1.Emprunt:3.Cyclofficine Account 1: 1.Capital:6.Emprunt,Dette:4.Etablissement_crédit Amount 1: -666 ; Don’t panic Account 2: 5.Finance: 5.Finance:1.Etablissement 5.Finance:1.Etablissement:2.Banque:002.Livret 5.Finance:8.Virement 5.Finance:1.Etablissement:1.Valeur 5.Finance:3.Caisse 5.Finance:8.Virement:0.Interne 5.Finance:1.Etablissement:1.Valeur:2.Chèque_à_encaisser 5.Finance:3.Caisse:1.Siège 5.Finance:8.Virement:1.Fonds 5.Finance:1.Etablissement:2.Banque:001.Courant 5.Finance:3.Caisse:2.Atelier Account 2: 5.Finance:1.Etablissement:2.Banque:001.Courant Amount 2 [666.0]: Account 3 (or . or enter to finish this transaction): . 2014/07/29 Trololo 1.Capital:6.Emprunt,Dette:4.Etablissement_crédit -666 ; Don’t panic 5.Finance:1.Etablissement:2.Banque:001.Courant 666.0 Save this transaction to the journal ? [y]: y Saved. Starting the next transaction (. or ctrl-D/ctrl-C to quit) Date [2014/07/29]: . ---- == Exercice comptable ifdef::backend-slidy2[>>>] === Plan comptable d’une association //NOTE: Brouillon de documentation @ https://wiki.cyclocoop.org/Comptabilité/Document/Plan_comptable/[] [source,hledger] ---- include::data/Cyclofficine.Plan_comptable.hledger[] ---- //[cols="a,a"] //|================================== //| //[float] //+ //[source,hledger] //---- //01/01 Vélo ; Écriture d’engagement (pièce comptable : facture) // 7.Produit:0.Vente:1.Produit_fini:1.Vélo -80 // 5.Finance:1.Etablissement:1.Valeur:2.Chèque_à_encaisser 80 //01/02 Chèque ; Écriture de paiement (pièce comptable : relevé de compte) // 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++ //|================================== === Relation de Chasles par écritures d’[black]*engagement* et de [black]*paiement* ++hledger++ laisse l’humain s’occuper de ce principe de la tâche comptable qui traduit la réalité temporelle des mouvements d’argent. [source,hledger] ---- 01/01 Prestation ; Écriture d’engagement (pièce comptable : facture) 7.Produit:0.Vente:6.Prest'action -700,00 4.Tiers:1.Client:1.Client:1.Bien,Prestation:007.Mairie_du_XI 700,00 01/14 Virement ; Écriture de paiement (pièce comptable : relevé de compte) 4.Tiers:1.Client:1.Client:1.Bien,Prestation:007.Mairie_du_XI -700,00 5.Finance:1.Etablissement:2.Banque:001.Courant 700,00 ---- ==== Soldes nuls souhaitables - Écritures des recettes + 1. latexmath:[$\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) (+/- chèques non déposés en banque) + NOTE: vérifier qu’il ne reste plus de chèques comptabilisés dans le tiroir 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) - Écritures de paye + TODO == Import et export avec ++hledger++ Comme la plupart des logiciels de comptabilité, ++hledger++ interropère avec le format de tableaux http://en.wikipedia.org/wiki/Comma-separated_values[CSV] ++hledger-print-csv++:: + [source,sh] ---- % hledger-print-csv -f data/exemple-syntaxe.ledger sys::[.../script/hledger-print-csv -f data/exemple-syntaxe.ledger] ---- ++*.csv.rules++:: http://hledger.org/manual#csv-files[] + [source,txt] ---- % cat banque-postale.livret_A.csv.rules skip 1 fields date,description,amount date-format %-d/%-m/%Y if .INTERETS ACQUIS DECOMPTE D'INTERETS . account1 Banque:Postale:Livret_A account2 Recette:Intérêts:Inflation ---- .Pour des besoins plus complexes - https://github.com/eval/total_recall[] - https://github.com/quentinsf/icsv2ledger[] - ou script sur mesure (ex. ++hledger-of-oxygen-csv.pl++) === Feuilles de calculs des documents comptables ifdef::backend-slidy2[>>>] ==== Bilan financier TODO ifdef::backend-slidy2[>>>] ==== Comptes de résultats TODO == Installer `hledger` * http://hledger.org/installing[] [source,sh] .Debian/jessie ---- % sudo apt-get install hledger hledger-web ---- ifdef::backend-slidy2[>>>] === Via `cabal` * http://www.haskell.org/cabal/[] [source,sh] .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 ---- [source,sh] .Mise-à-jour ---- % cabal install --reinstall hledger hledger-web ---- ifdef::backend-slidy2[>>>] ==== Version de développement [source,sh] ---- % git clone http://github.com/simonmichael/hledger.git ~/src/hledger % cd ~/src/hledger % cabal install --reinstall --force-reinstalls \ ./hledger-lib ./hledger ./hledger-web ---- === Utiliser un éditeur de texte structuré (`vim`) Coloration syntaxique sur mesure:: * ++hledger.vim++ + [source,vim] .~/.vimrc ---- autocmd BufNewFile,BufRead *.hledger,*.ledger setfiletype hledger ---- Complètement automatique des comptes (``):: + * https://github.com/Shougo/neocomplete.vim[] * https://github.com/Shougo/neocomplcache.vim[] + NOTE: Besoin de rajouter ++vim/autoload/neocomplcache/filters/sorter_bytes.vim++. + [source,vim] .~/.vimrc ---- autocmd Filetype hledger set iskeyword+=.,38,39,40,41,44,45,58 " ---- Alignement automatique des montants:: + * https://github.com/junegunn/vim-easy-align[] + [source,vim] .~/.vimrc ---- let g:easy_align_ignore_groups = ['Comment', 'String', 'hledgerTransaction'] ---- ifdef::backend-slidy2[>>>] ==== Suivre les modifications à plusieurs et/ou à distance (`git`) TODO == +++hledger-web+++ * http://localhost:5000[] + TODO == Scripter ++hledger++ [source,sh] .Installer un script ++hledger++ ---- % echo 'PATH="$HOME/src/hledger/extra:$PATH"' >>~/.profile % exit # NOTE: recharge ~/.profile % ghc ~/src/hledger/extra/hledger-SCRIPT.hs ---- .Idées de scripts * Vérifier l’ordre des dates. * Chercher des écritures doublonnes. == Merci .Luca Pacioli image::data/Luca_Pacioli_(Gemaelde).jpeg[] ifdef::backend-slidy2[] [hledgersplash,position: absolute; left: 50%; top: 10%;] &&&& image::data/hledger.splash.png[hledgersplash] &&&& endif::backend-slidy2[]