From 107f4fc174c14437a7c42bbfa6ebcf5f8ccb01d0 Mon Sep 17 00:00:00 2001 From: Vincent Le Gallic Date: Fri, 11 Mar 2016 05:41:03 +0100 Subject: [PATCH] =?utf8?q?[bde/compta]=20scripts=20pour=20faciliter=20la?= =?utf8?q?=20v=C3=A9rification=20de=20r=C3=A9partition=20par=20cat=C3=A9go?= =?utf8?q?ries?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- bde/compta/compare_descriptions_csvs.py | 92 +++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100755 bde/compta/compare_descriptions_csvs.py diff --git a/bde/compta/compare_descriptions_csvs.py b/bde/compta/compare_descriptions_csvs.py new file mode 100755 index 0000000..d600220 --- /dev/null +++ b/bde/compta/compare_descriptions_csvs.py @@ -0,0 +1,92 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- + +""" +Pour comparer l'ensemble des descriptions des transactions du Bde +avec le contenu de fichiers (un par catégorie) pour détecter un oubli. + +Mange une liste de fichiers qui contiennent une description par ligne. +Détecte les doublons, et vérifie que toutes les descriptions +des transactions dont le BDE est destinataire sont bien +dans un des fichiers. +""" + +import os +import glob +import collections +import argparse + +import base + +def get_descriptions_fichiers(filenames): + """Récupère les descriptions dans les fichiers.""" + descrs_files = [[d.rstrip("\n") for d in open(f).readlines()] for f in filenames] + descrs_files = sum(descrs_files, []) + return descrs_files + +def get_descriptions_bdd(debut=None, fin=None): + """ + Récupère les descriptions des transactions dont le BDE est destinataire, + de montant non nul, et entre ``debut`` et ``fin``. + """ + con, cur = base.getcursor() + req = """ + SELECT DISTINCT description + FROM transactions + WHERE montant != 0 + AND valide + AND destinataire = 0 + AND date >= %s + AND date <= %s; + """ + if debut is None: + debut_replace = "now() - '1 year'::interval" + else: + debut_replace = "%(debut)s" + if fin is None: + fin_replace = "now()" + else: + fin_replace = "%(fin)s" + req_degueux = req % (debut_replace, fin_replace) + # Si req_degueux n'a pas de %, avec le remplacement dico, ça passe sans problème + cur.execute(req_degueux, {"debut" : debut, "fin" : fin}) + descrs_bdd = [r["description"] for r in cur.fetchall()] + return descrs_bdd + +def detect(descrs_files, descrs_bdd): + """ + Fait la comparaison pour montrer les absents quelque part et afficher les doublons. + Renvoie 2 listes. + """ + absents = list(set(descrs_bdd).difference(descrs_files)) + absents.sort() + counter = collections.Counter(descrs_files) + doublons = [descr for (descr, count) in counter.iteritems() if count > 1] + return absents, doublons + +def main(args): + """Fait le boulot.""" + if args.filenames is None: + filenames = glob.glob("*.csv") + else: + filenames = args.filenames + descrs_files = get_descriptions_fichiers(filenames) + descrs_bdd = get_descriptions_bdd(args.debut, args.fin) + absents, doublons = detect(descrs_files, descrs_bdd) + print "Présents dans la BDD et pas dans les fichiers, ou le contraire :" + print "\n".join(absents) + print "En double dans les fichiers :" + print "\n".join(doublons) + + +parser = argparse.ArgumentParser(description=__doc__) + +parser.add_argument('-d', '--debut', type=str, help="Date de début (par défaut 'now - 1 year')", action="store") +parser.add_argument('-f', '--fin', type=str, help="Date de fin (par défaut 'now')", action="store") + +parser.add_argument("filenames", nargs="*", type=str, help="Un fichier par catégorie") + +if __name__ == "__main__": + args = parser.parse_args() + print args.__dict__ + main(args) -- 2.39.2