Skip to content

Commit d26d981

Browse files
committed
Merge branch 'csv' of github.com:aparcar/rechnung into develop
2 parents 5adb5bc + 62190ee commit d26d981

File tree

3 files changed

+69
-0
lines changed

3 files changed

+69
-0
lines changed

rechnung/cli.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
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 create_contracts, render_contracts, send_contract, get_contracts
8+
from .transactions import read_csv_files
89

910
cwd = os.getcwd()
1011

@@ -55,6 +56,19 @@ def print_contracts():
5556
print(f"{cid}: {slug} {data['start']} {total_monthly}€")
5657

5758

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

rechnung/settings.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
"contract_mail_template_file": "contract_mail_template.j2",
3737
"contract_template_file": "contract_template.j2.html",
3838
"contracts_dir": "contracts",
39+
"csv_dir": "csv",
3940
"delivery_date_format": "%d. %B %Y",
4041
"invoice_css_asset_file": "invoice.css",
4142
"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)