158 lines
5.0 KiB
Python
158 lines
5.0 KiB
Python
import csv
|
|
from functools import reduce
|
|
import re
|
|
|
|
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("konto.csv", "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("konto.csv", "w") as file:
|
|
file.writelines(lines[startLine:-1])
|
|
|
|
with open("konto.csv", "r") as file:
|
|
csvreader = csv.DictReader(file, delimiter=";")
|
|
for row in csvreader:
|
|
result.append(row)
|
|
with open("konto.csv", "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"] = sumVal + debetVal
|
|
debetVal = 0
|
|
toDel.append(dVerf)
|
|
else:
|
|
sums[kVerf]["value"] = sumVal + debetVal
|
|
debetVal = debetVal - sumVal
|
|
sums[kVerf]["debets"] = sums[kVerf]["debets"] + [dVerf]
|
|
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"])
|