--- /dev/null
+#!/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)