import csv from functools import reduce import re import sys if len(sys.argv) < 2: path2file = "konto.csv" else: path2file = sys.argv[1] def float2(value, default=0.0): if value is None: return default try: return float(value) except ValueError: return default print("Detta program rapporterar skillnader mellan verifikat som refererar till varandra genom beskrivningen av verifikatet. Den utgår från krediter och hittar matchande debeter") lines = [] result = [] with open(path2file, "r") as file: lines = file.readlines() startLine = 12 # READING for i, line in enumerate(lines): if "Konto" in line and "Verifikation" in line: startLine = i break with open(path2file, "w") as file: file.writelines(lines[startLine:-1]) with open(path2file, "r") as file: csvreader = csv.DictReader(file, delimiter=";") for row in csvreader: result.append(row) with open(path2file, "w") as file: file.writelines(lines) # FILE RESTORED, PARSE DATA krediter = {} debeter = {} verfs = {} sums = {} header = result.pop(0) for line in result: if not line['"Verifikation"']: continue verf = line['"Verifikation"'].replace(" ","") if verf not in verfs.keys(): verfs[verf] = line verfs[verf]["Corrections"] = [] verfs[verf]["Value"] = float2(line['"Debet"'].replace(",",".").replace(" ","")) verfs[verf]["Value"] -= float2(line['"Kredit"'].replace(",",".").replace(" ","")) else: verfs[verf]["Value"] -= float2(line['"Kredit"'].replace(",",".").replace(" ","")) verfs[verf]["Value"] += float2(line['"Debet"'].replace(",",".").replace(" ","")) ## ELIMINATE CORRECTIONS verfs = dict(reversed(sorted(verfs.items(), key = lambda x: int(x[0][1:])))) newVerfs = dict(verfs) corrections = [] for verf, line in verfs.items(): if "Korrigering" in line['"Beskrivning"']: corrections.append(verf) toDelete = [] missingVerfs = [] for verf, line in verfs.items(): if verf in reduce(lambda x,y: x + y, list(map(lambda x: [x[0]] + x[1], toDelete)),[]): continue if "Korrigering" in line['"Beskrivning"']: toRemove = re.findall("(A\d+)(?:\D){0,1}",line['"Beskrivning"'])[0] if toRemove not in verfs.keys(): missingVerfs.append(toRemove) else: newVerfs[toRemove]["Corrections"].append(verf) newVerfs[toRemove]["Corrections"].extend(newVerfs[verf]["Corrections"]) newVerfs[toRemove]["Value"] += line["Value"] ### check if toRemove verf should be removed if abs(newVerfs[toRemove]["Value"]) < 0.0001: toDelete.append((toRemove, newVerfs[toRemove]["Corrections"])) elif len(line["Corrections"]) > 0: toDelete.append((verf, [None] + line["Corrections"])) verfs = newVerfs if len(missingVerfs) > 0: print("") print(f"VARNING! {missingVerfs} saknas i verifikat listan men refereras till av korrektioner!") print("") if len(toDelete) > 0: print(f"Tar bort {len(toDelete)} korrigeringspar...") for v, ks in toDelete: if ks[0] == None: print(f" Verifikaten {ks[1:]} delkorrigerar {v}") ks = ks[1:] else: print(f" Verifikaten {ks} korrigerar bort hela {v}") del verfs[v] for k in ks: del verfs[k] ## FINISH PARSING DATA for verf, line in verfs.items(): if line["Value"] < 0: krediter[verf] = line elif line["Value"] > 0: debeter[verf] = line # FIND DIFFS AND LOG INTO DATA STRUCTURE print("Beräknar skillnader mellan utbetalningar och utlägg") for kVerf, kLine in krediter.items(): sums[kVerf] = {"value": kLine["Value"], "debets": [], "date": kLine['"Datum"']} toDel = [] for dVerf, dLine in debeter.items(): debetVal = dLine["Value"] for kVerf in re.findall("(A\d+)(?:\D){0,1}",dLine['"Beskrivning"']): if debetVal == 0: continue if kVerf not in sums: if kVerf not in corrections: print(f" I debeterande verifikat {dVerf} berörs {kVerf}, men {kVerf} hittas inte. (saknas kostnadsställe?)") continue sumVal = sums[kVerf]["value"] if abs(sumVal + debetVal) < 0.0001: sums[kVerf]["value"] = 0 debetVal = 0 toDel.append(dVerf) elif sumVal + debetVal < 0: sums[kVerf]["value"] += debetVal debetVal = 0 toDel.append(dVerf) else: sums[kVerf]["value"] = 0 debetVal = debetVal + sumVal sums[kVerf]["debets"] = sums[kVerf]["debets"] + [dVerf] if abs(debetVal) > 0.0001: debeter[dVerf]["Value"] = debetVal for dVerf in list(set(toDel)): del debeter[dVerf] # PRINT! print("---------------------") print("Nedan är alla utlägg/kredit verifikat och dess tillhörande betalningar.") for verf, a in sums.items(): if abs(a["value"]) > 0.0001: print(" VARNING! Ofullständig matchning i ",verf, ": ", a) else: print(f"{verf}: {a}") print("") print("Här kommer omatchade debeter") for debet, debetLine in debeter.items(): print(debet + ": " + debetLine['"Beskrivning"'] + " -- ", debetLine["Value"])