*

Ma comptabilité, une série temporelle comme les autres - partie 6 - Les FEC et le compte de résultat


29/10/2021 warp10 timeseries comptabilité résultat fec dashboard discovery

Suite de notre épopée :

Dans ce sixième et dernier billet pour cette série, nous continuons avec les Fichier d’Ecritures Comptables (FEC) pour produire le compte de résultat et déterminer ainsi le bénéfice de l’exercice en cours. Il faut donc prendre toutes les opérations en classe 6 (charges) et 7 (produits). Pour chaque classe de compte, il peut y avoir des crédits ou des débits (ex pour un compte de classe 7 : un avoir sur une facture émise). C’est donc un chouilla plus compliqué que le compte de trésorerie.

Depuis le dernier billet, j’ai légèrement fait évoluer le modèle de données :

  • Initialement, j’avais : <société>.<bilan ou resultat>.<classe de compte>.<type d'opération: credit ou debit>
  • Cela a évolué vers : <société>.<bilan ou resultat>.<classe de compte> ; le type d’opération est maintenant un label

Pour un crédit de 100€ avec une référence de pièce à 1234 pour le compte 706, on passe donc de :

<Timestamp de l'écriture comptable>// cerenit.resultat.706.credit{PieceRef=1234} 100

à :

<Timestamp de l'écriture comptable>// cerenit.resultat.706{PieceRef=1234, operation=credit} 100

Compte de résultat

"<readToken>" "readToken"  STORE

// Récupération de toutes les opérations de crédit pour les comptes charges (classe 6xx)
// Le SORT permet d'être sur d'avoir toutes les opérations triées par date
// Stockage du résultat dans une variable
[ $readToken '~comptabilite.resultat.6.*' { "operation" "credit" } '2020-01-01T00:00:00Z' '2020-12-31T23:59:59Z' ] FETCH
MERGE
SORT
'charges_credit' RENAME
'charges_credit' STORE


// Récupération de toutes les opérations de débit pour les comptes charges (classe 6xx)
// Le SORT permet d'être sur d'avoir toutes les opérations triées par date
// Stockage du résultat dans une variable
[ $readToken '~comptabilite.resultat.6.*' { "operation" "debit" } '2020-01-01T00:00:00Z' '2020-12-31T23:59:59Z' ] FETCH
MERGE
SORT
'charges_debit' RENAME
'charges_debit' STORE

// Fusion des deux listes de séries en une liste qui va avoir l'ensemble des opérations
// Les opérations de débit sont mis en valeur négative du calcul du solde
// Le SORT permet d'être sur d'avoir toutes les opérations triées par date
// Stockage du résultat dans une variable qui contient l'ensemble des opérations
[
  $charges_debit -1 *
  $charges_credit
] MERGE
SORT
'charges_flux' RENAME
'charges_flux' STORE

// Même opération pour les comptes de produit (7xx)
[ $readToken '~comptabilite.resultat.7.*' { "operation" "credit" } '2020-01-01T00:00:00Z' '2020-12-31T23:59:59Z' ] FETCH
MERGE
SORT
'produits_credit' RENAME
'produits_credit' STORE

[ $readToken '~comptabilite.resultat.7.*' { "operation" "debit" } '2020-01-01T00:00:00Z' '2020-12-31T23:59:59Z' ] FETCH
MERGE
SORT
'produits_debit' RENAME
'produits_debit' STORE

[
  $produits_debit -1 *
  $produits_credit 
] MERGE
SORT
'produits_flux' RENAME
'produits_flux' STORE

// Fusion des 2 flux d'opérations (charges et produits) pour avoir une vision temporelle de ces opérations
// Le SORT permet d'être sur d'avoir toutes les opérations triées par date
// Renommage de la série en "compte_resultat" qu'elle va permettre de batir
// Somme cumulée de l'ensemble des opérations pour avoir un solde à date
// Stockage sous la forme d'une variable
// Affichage de la variable
[
  $produits_flux
  $charges_flux
] MERGE
SORT
'compte_resultat' RENAME
[ SWAP mapper.sum MAXLONG 0 0 ] MAP
'compte_resultat' STORE
$compte_resultat

Ce qui nous donne dans le Studio :

warp10 - compte de résultat

Du précédent billet et ce celui-ci, nous avons donc :

  • Un compte de résultat annuel
  • Un compte de trésorerie annuel

Tout ce qu’il faut donc pour faire un dashboard avec Discovery. Il faut dire que le billet Covid Tracker built with Warp 10 and Discovery et dans une moindre mesure Server monitoring with Warp 10 and Telegraf donnent accès à plein d’options pour réaliser ses dashboards.

Macros

Je pourrais mettre le code de mes requêtes directement dans les dashboards mais j’aime pas trop quand des tokens se balladent dans les pages web. Du coup, je vais déporter le code dans des macros. J’ai églément rendu les macro dynamiques dans le sens où elles prennent une année en paramètre pour afficher les données de l’année en question.

On a déjà vu le fonctionnement des macros précédemment, je ne reviendrais donc pas dessus.

La macro du compte de résultat à titre d’exemple :

<%
    {
        'name' 'cerenit/accountancy/compte-resultat'
        'desc' 'Function to calculate the cumulative benefit (or loss) of the company'
        'sig' [ [ [ [  'year:LONG' ] ]  [ 'result:GTS' ] ] ]
        'params' {
            'year' 'Year, YYYY'
            'result' 'GTS'
        }
        'examples' [
    <'
2020 @cerenit/accountancy/compte-resultat
    '>
    ]
    } INFO

    // Actual code
    SAVE 'context' STORE

    TOLONG // When called from dashboard, it's a string - so convert paramter to LONG first
    'year' STORE // Save parameter as year
    
    // Compute 1st Jan of given year
    [ $year 01 01 ] TSELEMENTS-> ISO8601 
    'start' STORE
    
    // Compute 31 Dec of given year
    [ $year 12 31 23 59 59 ] TSELEMENTS-> ISO8601 
    'end' STORE
    
    "<readToken>" "readToken"  STORE

    [ $readToken '~comptabilite.resultat.6.*' { "operation" "credit" } $start $end ] FETCH
    MERGE
    SORT
    'charges_credit' RENAME
    'charges_credit' STORE

    [ $readToken '~comptabilite.resultat.6.*' { "operation" "debit" } $start $end ] FETCH
    MERGE
    SORT
    'charges_debit' RENAME
    'charges_debit' STORE

    [
    $charges_debit -1 *
    $charges_credit
    ] MERGE
    SORT
    { NULL NULL } RELABEL
    'charges_flux' RENAME
    'charges_flux' STORE

    [ $readToken '~comptabilite.resultat.7.*' { "operation" "credit" } $start $end ] FETCH
    MERGE
    SORT
    'produits_credit' RENAME
    'produits_credit' STORE

    [ $readToken '~comptabilite.resultat.7.*' { "operation" "debit" } $start $end ] FETCH
    MERGE
    SORT
    'produits_debit' RENAME
    'produits_debit' STORE

    [
    $produits_debit -1 *
    $produits_credit 
    ] MERGE
    SORT
    { NULL NULL } RELABEL
    'produits_flux' RENAME
    'produits_flux' STORE

    [
    $produits_flux
    $charges_flux
    ] MERGE
    SORT
    'compte_resultat' RENAME
    [ SWAP mapper.sum MAXLONG 0 0 ] MAP
    'compte_resultat' STORE
    $compte_resultat

    $context RESTORE
%>
'macro' STORE
$macro

Comme le décrit l’exemple, si on veut le compte de résultat de l’année 2020, on utilisera le code suivant :

2020 @cerenit/accountancy/compte-resultat

J’ai profité de ce billet pour utiliser Warpfleet Synchronizer & Warpfleet Resolver pour simplifier le déploiement des macros ; cela explique que les signatures pour appeler les macros changent par la suite dans le dashboard.

Dashboards

Ci-après le code du dashboard :

<%
{
    'title' 'Comptabilité CérénIT'
    'description' 'Trésorerie et compte de résultat'
    'vars' {
        'myYear' 2020
    }    
    'tiles' [
        {
            'title' 'Informations'
            'type' 'display'
            'w' 11 'h' 1 'x' 0 'y' 0
            'data' {
                'data' 'R&eacute;sultat de la s&eacute;rie <a href="https://www.cerenit.fr/blog/premiers-pas-avec-warp10-comptabilite-et-previsions/">Ma comptabilit&eacute;, une s&eacute;rie temporelle comme les autres</a> et de l&apos;ingestion des Fichiers d&apos;&eacute;critures comptables.'
                'globalParams' { 'timeMode' 'custom' }
            }
        }
        {
            'title' 'Année'
            'type' 'input:list'
            'w' 1 'h' 1 'x' 11 'y' 0
            'data' {
                'data' [ '2017' '2018' '2019' '2020' ]
                'events' [ { 'type' 'variable' 'tags' 'year' 'selector' 'myYear' } ]
                'globalParams' { 'input' { 'value' '2020' } }   
            }
        }
        {
            'title' 'Trésorerie (annuel)'
            'type' 'line'
            'w' 6 'h' 2 'x' 0 'y' 1
            'macro' <% $myYear @cerenit/macros/treso %>
            'options' { 'eventHandler' 'type=(variable),tag=year' }
        }
        {
            'title' 'Compte de résultat (annuel)'
            'type' 'line'
            'w' 6 'h' 2 'x' 6 'y' 1
            'macro' <% $myYear @cerenit/macros/compteresultat %>
            'options' { 'eventHandler' 'type=(variable),tag=year' }
        }
        {
            'title' 'Trésorerie (pluri-annuelle)'
            'type' 'line'
            'w' 12 'h' 2 'x' 0 'y' 3
            'macro' <% [ 2017 $myYear ] @cerenit/macros/treso_multi %>
            'options' { 'eventHandler' 'type=(variable),tag=year' }
        }  
    ]
}
{ 'url' 'https://w.ts.cerenit.fr/api/v0/exec'  } 
@senx/discovery2/render
%>

et son rendu ou la version en ligne :

warp10 - dashboard

Dans le bloc global du dashboard, on définir une variable myYear, initialisée à 2020. Cette variable est mise à jour dynamiquement lorsque l’on choisit une valeur dans la liste déroulante du bloc “Année”.

<%
{
    'title' 'Comptabilité CérénIT'
    'description' 'Trésorerie et compte de résultat'
    'vars' {
        'myYear' 2020
    }    
    ...

Le bloc Année justement :

        {
            'title' 'Année'
            'type' 'input:list'
            'w' 1 'h' 1 'x' 11 'y' 0
            'data' {
                'data' [ '2017' '2018' '2019' '2020' ]
                'events' [ { 'type' 'variable' 'tags' 'year' 'selector' 'myYear' } ]
                'globalParams' { 'input' { 'value' '2020' } }   
            }
        }

C’est une liste déroulante (type: input:list) avec pour valeurs les années 2017 à 2020. Par défaut, elle est initialisée à 2020. Via le mécanisme des “events”, lorsqu’une valeur est choisie, celle-ci est émise sous la forme d’une variable, nommée myYear et ayant pour tag la valeur year.

Ainsi, si je sélectionne 2017 dans la liste, la variable myYear prendra cette valeur. Maintenant que la valeur est définie suite à mon choix et émise vers le reste du dashboard, il faut que les autres tiles récupèrent l’information.

Regardons le tile Trésorerie :

        {
            'title' 'Trésorerie (annuel)'
            'type' 'line'
            'w' 6 'h' 2 'x' 0 'y' 1
            'macro' <% $myYear @cerenit/macros/treso %>
            'options' { 'eventHandler' 'type=(variable),tag=year' }
        }

La récupération de la variable se fait via la proriété options et la récupération de l’eventHandler associé et défini précédemment.

Une fois récupérée, la variable myYear peut être utilisée dans le bloc macro et le tile est mis à jour dynamiquement.

En conséquence :

  • Les deux premiers tiles afficheront le solde de trésorerie et le compte de résultat de l’année sélectionnée
  • Le dernier tile affichera la trésorerie depuis début 2017 jusqu’à la fin d’année sélectionnée. Donc au minimum 2017 et au maximum 2017 > 2020.

Ainsi s’achève cette série sur les données comptable et les séries temporelles. Des analyses complémentaires pourraient être menées (analyse de stocks, réparition d’activité, etc) mais mes données comptables sont insuffisantes pour en valoir l’intérêt. J’espère néanmoins que cela aura sucité votre intérêt et ouvert des horizons.

Cette série fut aussi l’occasion de faire un tour de la solution Warp 10 et de voir :

  • l’ingestion de données,
  • la manipulation et l’analyse des données,
  • la mise en place de dashboards,
  • la projection de données avec les algorythmes de machine learning.

Si vous souhaitez poursuivre l’aventure et le sujet, n’hésitez pas à me contacter.

Syndication

Restez informé(s) de notre actualité en vous abonnant au flux du blog (Atom)

Nuage de tags

kubernetes docker timeseries influxdb warp10 traefik grafana ansible elasticsearch kafka postgres python aws sécurité terraform mysql redis telegraf ovh tick cassandra chronograf cloud dashboard docker-compose git hashicorp helm timescaledb flux ptsm swarm vector kapacitor podman rancher résilience test gcp gitlab influxdata log machine-learning monitoring prometheus s3 spark timescale vscode architecture arm comptabilité confluent devops gitlab-ci iac java ksql microservice nomad postgresql raspberrypi serverless service-mesh sql angularjs api bilan cert-manager cncf consul container cérénit dns flows gke graphql ingress javascript npm opensource operator optimisation perspective pipeline rook scaleway ssh stream vault warpscript windows cli containerd csp discovery documentation elastic forecast geospatial golang hpkp influxace iot jenkins kafka-streams kibana kubedb lambda lean licence maesh maintenance mariadb microsoft mobile nginx orientdb performance quasardb redhat registry rest rethinkdb reverse-proxy sauvegarde warpstudio agile anomalie apm arima audit automatisation azure bash big-data bigdatahebdo ceph certificat challenge ci/cd cluster continous-delivery continous-integration cookie data datatask dataviz dbt deployment diff facebook fec fluxlang framework gdpr grav hsts http/3 https hypriot hébergement ia influxdays istio jq json k3s lets-encrypt linux load-balancer longhorn meetup metabase molecule mongodb nosql nvidia openebs openssh ovhcloud percona php pip questdb reaper replication rootless rpi rsyslog runc scale secrets société solr sre systemd tempo timezone tls virtualenv vitess vue.js wagtail warpfleet yarn accessibilité acme adoptopenjdk agpl akka alerte alertes alerting alibaba amazon-emr amqp anonymisation anthos apache-pulsar ara arrow artefact automation automl banque bastion beam beat bi bme680 bootstrap bounded-context branche brigade browser buildah buildkit cahier-des-charges calico cassandra-reaper cd cdc cdk centos centralisation-de-logs certificats cgroups chart check checklist chrome ci cilium circuitpython clever-cloud clickhouse cloud-init cloud-native cloud-storage cloudflare clusterip cnab cni co2 cockroachdb code codeurs-en-seine commit confluence conftest consul-connect context continous-deployment conventional-commit coreos cors covid19 cqrs crash cri cron crontab csi csrf css curl d3.js daemonset data-engineer data-pipelining data.gouv.fr databricks datacenter date date-scientist ddd debezium debian delta deprek8 desktop devoxx dig distributed-systems dive docker-app docker-hub docker-registry docker-swarm dockershim documentdb dog dokcer données-personnelles draft drop-in duration déploiement développement-du-site e-commerce ebs ec2 edge elassandra electron elk engineering entreprise ergonomie etcd euclidia event-sourcing faas faisabilité falco falcor feature-policy fedora feed filebeat firebase firefox fish flash flask fleet flink fluentd formation foundation frenchtech frontend fsync fullstack git-filter-repo github gitignore glacier glowroot go google google-cloud-next gpg gpu grid géospatial hacker hadoop haproxy harbor hdfs header holt-winters html html5 http hue iaac ibm immutable incident index indluxdata influxcloud infrastructure-as-code ingénierie inspec jquery jvm jwt k3d k6 k8s k9s kaniko katz kotlin kubeadm kubecon kubectl label laravel leap-second lens letsencrypt libssh linky linter liste-de-diffusion lmap loadbalancer logstash logstatsh loi loki lstm mailing-list management maturité mesh mesos message metallb micro-service minio mot-de-passe mqtt multi-cloud médecine métrique n8n network newsletter nodejs nodeport notebook notifications nrtsearch null object-storage observability observabilité opa opendata openhab openmetrics openshit openstack openweb opnsense over-engineering packaging pandas parquet partiql password persistent-volume-claim pico pipenv pivot pod portainer portworx prediction prescience production promql prophet prévision psp ptyhon publicité pubsub pulsar push pyenv pérénnité qualité quay queue quic ram rambleed raml react readme recaptcha recherche redistimeseries reindex reinvent reliability remote-execution repository responsive retention-policy revocation revue-de-code rexec rgpd rhel rkt rolespec root rpo rto rust rwd résultat safe-harbor sarima scalabilité scanner schema scp sdk search select serverless-architecture service service-account service-worker setuptools sftp sha1 shard shard-duration shard-group sharding shell shipyard sidecar singer souveraineté-numérique spectre spinnaker spécifications sqlite sri ssh-agent ssl stabilité stash statistique storage sudo superset suse sympa sysdig syslog-ng sérénité task template terracost terrascan test-unitaire tidb tiers time timecale timer timestream tinygo training transformation travail trésorerie tsfr tsl ubuntu unikernel unit ux velero vendredi victoria-metrics vie-privée virtualbox virtualisation vm vnc volume voxxeddays vpc wasm web wireguard workflow yaml yield yq yubikey