Skip to content

Commit bdd7419

Browse files
authored
Merge pull request #10 from aparcar/csv
add csv parsing
2 parents a3f2310 + 5573b76 commit bdd7419

File tree

3 files changed

+70
-0
lines changed

3 files changed

+70
-0
lines changed

rechnung/cli.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from .settings import get_settings_from_cwd, copy_assets, create_required_settings_file
66
from .invoice import create_invoices, render_invoices, send_invoices
77
from .contract import render_contracts, send_contract, get_contracts
8+
from .transactions import read_csv_files
9+
810

911
cwd = os.getcwd()
1012

@@ -57,6 +59,19 @@ def print_contracts():
5759
print(f"{cid}: {slug} {data['start']} {total_monthly}€")
5860

5961

62+
@cli1.command()
63+
@click.argument("year", type=int)
64+
@click.argument("month", type=int)
65+
def print_csv(year, month):
66+
"""
67+
Parse CSV files for a specific year/month combo
68+
"""
69+
settings = get_settings_from_cwd(cwd)
70+
print(f"Parsing CSV files for {year}{month}")
71+
for transaction in read_csv_files(settings, year, month):
72+
print("{date}: {type[0]} {amount:>6}€ {sender}".format(**transaction))
73+
74+
6075
@cli1.command()
6176
def print_stats():
6277
"""

rechnung/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
"contract_mail_template_file": "contract_mail_template.j2",
3838
"contract_template_file": "contract_template.j2.html",
3939
"contracts_dir": "contracts",
40+
"csv_dir": "csv",
4041
"delivery_date_format": "%d. %B %Y",
4142
"invoice_css_asset_file": "invoice.css",
4243
"invoice_mail_template_file": "invoice_mail_template.j2",

rechnung/transactions.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import datetime
2+
import locale
3+
import os
4+
import os.path
5+
import yaml
6+
import csv
7+
import re
8+
from dateutil.parser import parse
9+
10+
from pathlib import Path
11+
12+
13+
def parser_gls(csv_path):
14+
"""
15+
Parses CSV files from the GLS bank
16+
"""
17+
groups = [
18+
r"(?P<type>Dauerauftragsbelast|Dauerauftragsgutschr|Überweisungsauftrag|Basislastschrift|Überweisungsgutschr\.)",
19+
r"(?P<subject>.*)IBAN:\s?(?P<iban>.+) BIC:\s?(?P<bic>.+)",
20+
]
21+
compiled_groups = re.compile("".join(groups))
22+
transactions = []
23+
24+
with open(csv_path, encoding="iso-8859-1") as csv_file:
25+
csv_reader = csv.reader(csv_file, delimiter=";")
26+
27+
for row in csv_reader:
28+
match = compiled_groups.match(row[8].replace("\n", ""))
29+
if match:
30+
transactions.append(
31+
{
32+
**match.groupdict(),
33+
"date": parse(row[0], dayfirst=True),
34+
"sender": row[3],
35+
"amount": float(row[11].replace(",", ".")),
36+
}
37+
)
38+
return transactions
39+
40+
41+
def read_csv_files(settings, year, month):
42+
"""
43+
Parses CSV files of a specific year/month combo
44+
"""
45+
transactions = []
46+
for bank in settings.csv_dir.iterdir():
47+
csv_path = bank / f"{year}{month:02}.csv"
48+
if csv_path.is_file():
49+
if bank.stem == "gls":
50+
transactions.extend(parser_gls(csv_path))
51+
else:
52+
print("Unknown CSV format")
53+
54+
return transactions

0 commit comments

Comments
 (0)