154 lines
4.3 KiB
Python
Executable file
154 lines
4.3 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
from os.path import basename
|
|
from beangulp import Ingest
|
|
from beangulp import mimetypes
|
|
from beangulp.importers import csvbase
|
|
from beangulp.testing import main
|
|
from beancount.core.data import Transaction, Posting
|
|
from deelnemers import deelnemers
|
|
|
|
|
|
participants = deelnemers()
|
|
|
|
|
|
class RaboAmount(csvbase.Amount):
|
|
def __init__(self, col):
|
|
super().__init__(col, subs={"\\+": "", ",": "."})
|
|
|
|
|
|
class Importer(csvbase.Importer):
|
|
encoding = "iso-8859-15"
|
|
|
|
date = csvbase.Date("Datum", "%Y-%m-%d")
|
|
payee = csvbase.Columns("Naam tegenpartij", "Tegenrekening IBAN/BBAN", sep="; ")
|
|
narration = csvbase.Columns(
|
|
"Omschrijving-1", "Omschrijving-2", "Omschrijving-3", sep=" "
|
|
)
|
|
amount = RaboAmount("Bedrag")
|
|
balance = RaboAmount("Saldo na trn")
|
|
|
|
def identify(self, filepath):
|
|
mimetype, encoding = mimetypes.guess_type(filepath)
|
|
if mimetype != "text/csv":
|
|
return False
|
|
with open(filepath, "rb") as fd:
|
|
head = fd.read(1024)
|
|
return head.startswith(
|
|
b'"IBAN/BBAN","Munt","BIC","Volgnr","Datum","Rentedatum","Bedrag","Saldo na trn","Tegenrekening IBAN/BBAN"'
|
|
)
|
|
|
|
def filename(self, filepath):
|
|
return "rabobank." + basename(filepath)
|
|
|
|
|
|
def guess_contra(entry):
|
|
posting = entry.postings[0]
|
|
|
|
def have_keyword(*keywords):
|
|
l_description = entry.narration.lower()
|
|
return any(kw in l_description for kw in keywords)
|
|
|
|
if entry.payee == "Kosten" or (
|
|
entry.payee == "Rabobank; NL89RABO0111741386"
|
|
and entry.narration.startswith("Kosten")
|
|
):
|
|
return "Uitgaven:Bankkosten"
|
|
|
|
if entry.payee == "Stichting Bitlair; NL09RABO3159222187":
|
|
return "Activa:Spaarrekening"
|
|
|
|
if (
|
|
entry.payee == "Symbiose Beheer B.V.; NL84ABNA0630587221"
|
|
and posting.units.number < -3400
|
|
):
|
|
return "Uitgaven:Huur"
|
|
|
|
if (
|
|
entry.payee == "Stichting EventInfra; NL59RABO0312574800"
|
|
and entry.narration == "Verhuur opslagruimte "
|
|
):
|
|
return "Activa:Debiteuren:EventInfra"
|
|
|
|
if (
|
|
entry.payee == "JONGE ONDERZOEKERS AMERS; NL30ABNA0119774844"
|
|
and 590 < posting.units.number < 700
|
|
):
|
|
return "Activa:Debiteuren:DJO"
|
|
|
|
if (
|
|
entry.payee == "Furthermore B.V.; NL06REVO8135470894"
|
|
and 600 < posting.units.number < 800
|
|
):
|
|
return "Activa:Debiteuren:UnicornDept"
|
|
|
|
if entry.payee == "Gebr. Schurman GmbH; DE68441600141300702500":
|
|
return "Uitgaven:Bar:Mate"
|
|
|
|
if entry.payee == "Sligro ZB 5037":
|
|
return "Uitgaven:Bar:Snacks"
|
|
|
|
if entry.payee == "STATIEGELD NEDERLAND; NL59ABNA0100073913":
|
|
return "Uitgaven:Bar"
|
|
|
|
if entry.narration.startswith("Decla") and posting.units.number < 0:
|
|
return "Passiva:Declaraties"
|
|
|
|
if have_keyword(
|
|
"deposit",
|
|
"revbank",
|
|
" bar ",
|
|
"kassa vulling",
|
|
"desposit",
|
|
"(RB QR)",
|
|
"rev-bank",
|
|
" bank",
|
|
"elena transfer",
|
|
"barsaldo",
|
|
):
|
|
return "Passiva:RevBank"
|
|
|
|
if entry.payee == "Stichting Mollie Payments; NL70CITI2032329018":
|
|
return "Passiva:RevBank"
|
|
|
|
for p in participants:
|
|
if (
|
|
hasattr(p, "maandbedrag")
|
|
and hasattr(p, "ibans")
|
|
and p.maandbedrag == posting.units.number
|
|
and any(iban in entry.payee for iban in p.ibans)
|
|
):
|
|
return f"Activa:Debiteuren:Deelnemers:{p.nickname.title().replace('_', '')}"
|
|
|
|
return None
|
|
|
|
|
|
def classify_hook(extracted_entries_list, ledger_entries):
|
|
def _classify(entry):
|
|
if not isinstance(entry, Transaction):
|
|
return entry
|
|
contra = guess_contra(entry)
|
|
posting = entry.postings[0]
|
|
entry.postings.append(
|
|
Posting(
|
|
contra or "Inkomsten:TODO",
|
|
-posting.units,
|
|
posting.cost,
|
|
posting.price,
|
|
None if contra else "!",
|
|
None,
|
|
)
|
|
)
|
|
return entry
|
|
|
|
return [
|
|
(filename, [_classify(entry) for entry in entries], account, importer)
|
|
for filename, entries, account, importer in extracted_entries_list
|
|
]
|
|
|
|
|
|
if __name__ == "__main__":
|
|
importers = [Importer("Activa:Betaalrekening", "EUR")]
|
|
hooks = [classify_hook]
|
|
main = Ingest(importers, hooks)
|
|
main()
|