]> gitweb.pimeys.fr Git - scripts-20-100.git/commitdiff
[bde/credits_duplicates] Pour trouver les crédits note kfet dupliqués
authorVincent Le Gallic <legallic@crans.org>
Wed, 10 Feb 2016 04:24:56 +0000 (05:24 +0100)
committerVincent Le Gallic <legallic@crans.org>
Wed, 10 Feb 2016 04:25:25 +0000 (05:25 +0100)
bde/credits_duplicates.py [new file with mode: 0755]

diff --git a/bde/credits_duplicates.py b/bde/credits_duplicates.py
new file mode 100755 (executable)
index 0000000..d2d7575
--- /dev/null
@@ -0,0 +1,134 @@
+#!/usr/bin/env python
+# -*- encoding: utf-8 -*-
+
+""" Pour trouver les chèque dupliqués sur la note. """
+
+import psycopg2
+import psycopg2.extras
+import collections
+import pprint
+import subprocess
+
+import pretty_print
+
+def getcursor():
+    con = psycopg2.connect(database="note")
+    con.set_client_encoding("utf-8")
+    return (con, con.cursor(cursor_factory = psycopg2.extras.DictCursor))
+
+def get_data(cur, delai='1 minute'):
+    """
+    Récupère les paires de crédits effectués à moins de ``delai`` d'intervalle.
+    ``delai`` est un chaîne de caractères que PostGreSQL comprendra comme une durée.
+    Les crédits doivent êtres valides, de même destinataire, de même montant.
+    Pour les crédits chèque, virement et carte bancaire, on vérifie qu'ils aient le même prénom,nom
+    """
+    req_create_credits = """
+    CREATE TEMPORARY TABLE credits AS (
+    (
+     SELECT t.*, c.prenom, c.nom FROM transactions t, cheques c
+     WHERE t.type = 'crédit' AND t.emetteur = -1 AND t.id = c.idtransaction
+    )
+    UNION
+    (
+     SELECT t.*, v.prenom, v.nom FROM transactions t, virements v
+     WHERE t.type = 'crédit' AND t.emetteur = -3 AND t.id = v.idtransaction
+    )
+    UNION
+    (
+     SELECT t.*, cb.prenom, cb.nom FROM transactions t, carte_bancaires cb
+     WHERE t.type = 'crédit' AND t.emetteur = -4 AND t.id = cb.idtransaction
+    )
+    UNION
+    (
+     SELECT t.*, '', '' FROM transactions t
+     WHERE t.type = 'crédit' AND t.emetteur = -1
+    ));
+    """
+    cur.execute(req_create_credits)
+
+    req = u"""
+        SELECT
+            t1.id AS id1,
+            t2.id AS id2,
+            t1.date AS date1,
+            t2.date AS date2,
+            t2.date - t1.date AS deltaT,
+            t1.montant,
+            t1.destinataire,
+            c.pseudo AS destp,
+            t1.description AS desc1,
+            t2.description AS desc2
+        FROM credits t1,credits t2, comptes c
+        WHERE t1.destinataire = c.idbde
+          AND t1.date >= '2016-01-01'
+          AND t2.date >= '2016-01-01'
+          AND t1.type='crédit'
+          AND t2.type='crédit'
+          AND t1.id != t2.id
+          AND t1.valide
+          AND t2.valide
+          AND t1.destinataire = t2.destinataire
+          AND t1.montant = t2.montant
+          AND t1.prenom = t2.prenom
+          AND t1.nom = t2.nom
+          AND (t2.date - t1.date) <= %(delai)s
+          AND (t2.date - t1.date) >= '0 s';
+    """
+    cur.execute(req, {"delai" : delai})
+    l = cur.fetchall()
+    return l
+
+def sort_by_blocks(data):
+    """
+    Regroupe les transactions qui vont ensemble.
+    Sort une liste de chaînes de caractères contenant les ids de chaque block comma-separated.
+    Oui, le format de sortie est dégueu, mais c'est nettement moin galère pour trouver les doublons.
+    """
+    map = collections.defaultdict(lambda : set())
+    for t in data:
+        id1, id2 = t["id1"], t["id2"]
+        if id1 in map:
+            s = map[id1]
+        elif id2 in map:
+            s = map[id2]
+        else:
+            s = set()
+        # Comme on touche s en place et que c'est le même mutable qui a été mis
+        # comme valeur des 2 clés, il sera modifié par les étapes suivantes aussi
+        s.add(id1)
+        s.add(id2)
+        map[id1] = map[id2] = s
+    # On a tous les blocks, reste à ne garder qu'un exemplaire de chaque
+    result = [list(s) for s in map.values()]
+    for l in result:
+        l.sort()
+    result = [", ".join([str(i) for i in l]) for l in result]
+    result = list(set(result))
+    return result
+
+def get_transactions(cur, ids):
+    """
+    Récupère les informations de toutes les transactions dans la liste d'identifiants ``ids``
+    qui doit être donné sous la forme d'une chaîne de caractères d'ids comma-separated.
+    """
+    # yuk, mais le format correspond à ce qu'outpute sort_by_blocks
+    cur.execute("SELECT * FROM credits WHERE id IN (%s)" % ids)
+    return cur.fetchall()
+
+
+if __name__ == "__main__":
+    con, cur = getcursor()
+    data = get_data(cur)
+    blocks = sort_by_blocks(data)
+    for b in blocks:
+        l = get_transactions(cur, b)
+        formatted = pretty_print.sql_pretty_print(l, keys=["id", "date", "type", "emetteur", "destinataire", "quantite", "montant", "description", "valide", "cantinvalidate"])
+        p = subprocess.Popen(["less"], stdin=subprocess.PIPE)
+        p.communicate(formatted.encode("utf-8"))
+        print formatted
+        print "IDs : %s" % b
+        idkeep = int(b.split(",")[0])
+        ans = raw_input("Ne garder que %s (= dévalider les autres) ? [o/N]" % idkeep)
+        if ans.lower() in ["o", "y"]:
+            print "bim !"