]> gitweb.pimeys.fr Git - scripts-20-100.git/blob - bde/compta/compare_descriptions_csvs.py
[bde/compta] scripts pour faciliter la vérification de répartition par catégories
[scripts-20-100.git] / bde / compta / compare_descriptions_csvs.py
1 #!/usr/bin/env python
2 # -*- encoding: utf-8 -*-
3
4 """
5 Pour comparer l'ensemble des descriptions des transactions du Bde
6 avec le contenu de fichiers (un par catégorie) pour détecter un oubli.
7
8 Mange une liste de fichiers qui contiennent une description par ligne.
9 Détecte les doublons, et vérifie que toutes les descriptions
10 des transactions dont le BDE est destinataire sont bien
11 dans un des fichiers.
12 """
13
14 import os
15 import glob
16 import collections
17 import argparse
18
19 import base
20
21 def get_descriptions_fichiers(filenames):
22 """Récupère les descriptions dans les fichiers."""
23 descrs_files = [[d.rstrip("\n") for d in open(f).readlines()] for f in filenames]
24 descrs_files = sum(descrs_files, [])
25 return descrs_files
26
27 def get_descriptions_bdd(debut=None, fin=None):
28 """
29 Récupère les descriptions des transactions dont le BDE est destinataire,
30 de montant non nul, et entre ``debut`` et ``fin``.
31 """
32 con, cur = base.getcursor()
33 req = """
34 SELECT DISTINCT description
35 FROM transactions
36 WHERE montant != 0
37 AND valide
38 AND destinataire = 0
39 AND date >= %s
40 AND date <= %s;
41 """
42 if debut is None:
43 debut_replace = "now() - '1 year'::interval"
44 else:
45 debut_replace = "%(debut)s"
46 if fin is None:
47 fin_replace = "now()"
48 else:
49 fin_replace = "%(fin)s"
50 req_degueux = req % (debut_replace, fin_replace)
51 # Si req_degueux n'a pas de %, avec le remplacement dico, ça passe sans problème
52 cur.execute(req_degueux, {"debut" : debut, "fin" : fin})
53 descrs_bdd = [r["description"] for r in cur.fetchall()]
54 return descrs_bdd
55
56 def detect(descrs_files, descrs_bdd):
57 """
58 Fait la comparaison pour montrer les absents quelque part et afficher les doublons.
59 Renvoie 2 listes.
60 """
61 absents = list(set(descrs_bdd).difference(descrs_files))
62 absents.sort()
63 counter = collections.Counter(descrs_files)
64 doublons = [descr for (descr, count) in counter.iteritems() if count > 1]
65 return absents, doublons
66
67 def main(args):
68 """Fait le boulot."""
69 if args.filenames is None:
70 filenames = glob.glob("*.csv")
71 else:
72 filenames = args.filenames
73 descrs_files = get_descriptions_fichiers(filenames)
74 descrs_bdd = get_descriptions_bdd(args.debut, args.fin)
75 absents, doublons = detect(descrs_files, descrs_bdd)
76 print "Présents dans la BDD et pas dans les fichiers, ou le contraire :"
77 print "\n".join(absents)
78 print "En double dans les fichiers :"
79 print "\n".join(doublons)
80
81
82 parser = argparse.ArgumentParser(description=__doc__)
83
84 parser.add_argument('-d', '--debut', type=str, help="Date de début (par défaut 'now - 1 year')", action="store")
85 parser.add_argument('-f', '--fin', type=str, help="Date de fin (par défaut 'now')", action="store")
86
87 parser.add_argument("filenames", nargs="*", type=str, help="Un fichier par catégorie")
88
89 if __name__ == "__main__":
90 args = parser.parse_args()
91 print args.__dict__
92 main(args)