from beancount.ingest import importer from beancount.core import data from beancount.core.number import D import csv class MyCSVImporter(importer.ImporterProtocol): """A Beancount importer for CSV files""" def identify(self, file): return file.name.endswith('.csv') def file_account(self, file): return "Assets:Bank:POSTBANK" def file_date(self, file): """Returns the unique date of the file, if any.""" # Optioneel: als je bestandsnaam een datum bevat return None def file_name(self, file): """Returns the unique name of the file, if any.""" # Optioneel: als je een unieke naam wilt baseren op het bestand return None def extract(self, file, existing_entries=None): """Extracts entries from a files.""" entries = [] with open(file.contents, encoding='utf-8') as f: reader = csv.reader(f, delimiter=';') for skip in range(0,8): next(reader, None) for index, row in enumerate(reader): if not row or not row[0]: continue # De index begint bij 0, dus de 12e kolom is index 11. # Boekingsdatum = index 0 # Ontvanger = index 3 # Omschrijving = index 4 # Bedrag = index 11 # Valuta = index 17 datum_str = row[0] ontvanter = row[3] omschrijving_str = row[4] bedrag_str = row[11] valuta = row [17] dag, maand, jaar = datum_str.split('.') transactie_datum = data.D(int(jaar)), int(maand), int(dag)) payee = ontvanter narration = omschrijving_str bedrag = D(bedrag_str).replace(',','.') meta = data.new_metadata(file.name, index) # Bepaal of het een inkomst of uitgave is op basis van het voorteken van het bedrag. if bedrag < D(0): # Uitgave: bedrag is negatief. # Geld gaat van de bankrekening naar een uitgavenrekening. tegenrekening = self._map_payee_to_account(payee + " " + omschrijving_str) postings = [ data.Posting(self.file_account(file), bedrag, data.get_currency_meta(currency), None, None, None), data.Posting(tegenrekening, -bedrag, data.get_currency_meta(currency), None, None, None), ] else: # Inkomsten: bedrag is positief. # Geld gaat van een inkomstenrekening naar de bankrekening. tegenrekening = self._map_payee_to_account(payee + " " + omschrijving_str) postings = [ data.Posting(tegenrekening, -bedrag, data.get_currency_meta(currency), None, None, None), data.Posting(self.file_account(file), bedrag, data.get_currency_meta(currency), None, None, None), ] transaction = data.Transaction( meta=meta, date=transactie_datum, flag='*', payee=payee, narration=narration, tags=data.frozenset(), links=data.frozenset(), postings=postings ) entries.append(transaction) return entries def _map_payee_to_account(self, payee): mapping = { "Lohn": "Income:Salary", "Miete": "Expenses:Rent", "Sachsen":"Expenses:Electricity", } for sleutelwoord, rekening in mapping.items(): if sleutelwoord.lower() in payee.lower(): return rekening return "Expenses:Uncategorized"