diff --git a/src/ofxstatement/plugins/raiffeisen.py b/src/ofxstatement/plugins/raiffeisen.py index 9455b13..e5d964a 100644 --- a/src/ofxstatement/plugins/raiffeisen.py +++ b/src/ofxstatement/plugins/raiffeisen.py @@ -3,10 +3,11 @@ # See README.rst for more information. import csv +import re from ofxstatement import statement from ofxstatement.parser import CsvStatementParser from ofxstatement.plugin import Plugin -from ofxstatement.statement import generate_transaction_id +from ofxstatement.statement import generate_transaction_id, BankAccount from ofxstatement.plugins.utils import \ clean_multiple_whitespaces, fix_amount_string @@ -42,11 +43,27 @@ def parse_record(self, line): line[3] = fix_amount_string(line[3]) line[1] = clean_multiple_whitespaces(line[1]) + memo = re.split( r'((?:(?:BIC|IBAN) )?(?:Auftraggeber|Zahlungsempfänger|Empfänger)|Verwendungszweck|Zahlungsreferenz|Auftraggeberreferenz|Empfänger-Kennung|Mandat|Kundendaten): ', line[1] ) + parsed_memo = { + 'Empfänger': re.sub(r'ONLINE BANKING VOM \d{2}.\d{2} UM \d{2}:\d{2}', '', re.sub(r'KONFORM \d+UEB\d+', '', memo.pop(0).replace( 'INTERNET-Überweisung', ''))) + } + for k, v in zip(memo[::2], memo[1::2]): + if ( k in parsed_memo ): + parsed_memo[k] = (parsed_memo[k] + " " + v).strip() + else: + parsed_memo[k] = v.strip() + # Create statement and fixup missing parts stmtline = super(RaiffeisenCsvParser, self).parse_record(line) stmtline.trntype = 'DEBIT' if stmtline.amount < 0 else 'CREDIT' + stmtline.payee = parsed_memo.get('Auftraggeber', parsed_memo.get('Zahlungsempfänger', parsed_memo.get('Empfänger'))) + stmtline.bank_account_to = BankAccount( + parsed_memo.get('BIC Auftraggeber', parsed_memo.get('BIC Zahlungsempfänger', parsed_memo.get('BIC Empfänger'))), + parsed_memo.get('IBAN Auftraggeber', parsed_memo.get('IBAN Zahlungsempfänger', parsed_memo.get('IBAN Empfänger'))) + ) + stmtline.check_no=parsed_memo.get('Auftraggeberreferenz') + stmtline.memo=parsed_memo.get('Verwendungszweck',parsed_memo.get('Zahlungsreferenz',parsed_memo.get('Kundendaten',stmtline.memo))) stmtline.id = generate_transaction_id(stmtline) - return stmtline @@ -55,7 +72,7 @@ class RaiffeisenPlugin(Plugin): def get_parser(self, filename): """Get a parser instance.""" - encoding = self.settings.get('charset', 'cp1252') + encoding = self.settings.get('charset', 'utf-8-sig') f = open(filename, 'r', encoding=encoding) parser = RaiffeisenCsvParser(f) parser.statement.account_id = self.settings.get('account', 'default') diff --git a/src/ofxstatement/plugins/tests/samples/raiffeisen-meinelba.csv b/src/ofxstatement/plugins/tests/samples/raiffeisen-meinelba.csv new file mode 100644 index 0000000..aaf680a --- /dev/null +++ b/src/ofxstatement/plugins/tests/samples/raiffeisen-meinelba.csv @@ -0,0 +1,4 @@ +01.08.2020;"Zahlungsempfänger: ABC Verwendungszweck: 123 IBAN Zahlungsempfänger: AT105400054865187431 BIC Zahlungsempfänger: RZBAATWWXXX Zahlungsempfänger: CDEF Empfänger-Kennung: AT7811000888784732 Auftraggeberreferenz: 13041299 Mandat: 31241 vom 03.09.2018";01.08.2020;-12,84;EUR;01.08.2020 04:04:12:350; +05.08.2020;"KONFORM 32000200805UEB09030000075 Empfänger: ABC Verwendungszweck: UEB Rate/Zinsen IBAN Empfänger: AT923219555763241828 BIC Empfänger: RLNWATWWXXX Empfänger: CDEF";06.08.2020;-121,31;EUR;05.08.2020 01:08:58:909; +05.08.2020;"ONLINE BANKING VOM 05.08 UM 11:20 Empfänger: ABC Zahlungsreferenz: Übertrag IBAN Empfänger: AT162011178222385438 BIC Empfänger: RLNWATWWXXX";05.08.2020;-400,00;EUR;05.08.2020 11:20:36:958; +13.08.2020;"Auftraggeber: EFG Verwendungszweck: Gutschrifts Nr. 123 vom 01.08.2020 IBAN Auftraggeber: AT83450700241402732222 BIC Auftraggeber: RLNWATWWXXX";13.08.2020;120,00;EUR;13.08.2020 09:03:53:715; diff --git a/src/ofxstatement/plugins/tests/test_raiffeisen.py b/src/ofxstatement/plugins/tests/test_raiffeisen.py index 5abd0a3..c4a5962 100644 --- a/src/ofxstatement/plugins/tests/test_raiffeisen.py +++ b/src/ofxstatement/plugins/tests/test_raiffeisen.py @@ -65,9 +65,7 @@ def test_line3_service_fee(self): def test_line4_elba_payment(self): line = self.statement.lines[4] self.assertEqual(line.amount, Decimal('-175.16')) - self.assertEqual( - line.memo, "ELBA-INTERNET VOM 29.06 UM 09:16 Empfänger: A person " - "Verwendungszweck: Invoice number 10") + self.assertEqual(line.memo, "Invoice number 10") self.assertEqual(line.trntype, "DEBIT") self.assertEqual(line.date, datetime.datetime(2013, 7, 1, 0, 0)) self.assertEqual(line.id, generate_transaction_id(line)) @@ -75,9 +73,7 @@ def test_line4_elba_payment(self): def test_line5_debit(self): line = self.statement.lines[5] self.assertEqual(line.amount, Decimal('-100')) - self.assertEqual( - line.memo, "Lastschrift Auftraggeber: A company " - "Kundendaten: 000000000000 111111111111 Verwendungszweck: reason") + self.assertEqual(line.memo, "reason") self.assertEqual(line.trntype, "DEBIT") self.assertEqual(line.date, datetime.datetime(2013, 7, 1, 0, 0)) self.assertEqual(line.id, generate_transaction_id(line)) @@ -85,10 +81,61 @@ def test_line5_debit(self): def test_line6_credit(self): line = self.statement.lines[6] self.assertEqual(line.amount, Decimal('123.60')) - self.assertEqual( - line.memo, "Gutschrift Auftraggeber: A person Kundendaten: reason") + self.assertEqual(line.memo, "reason") self.assertEqual(line.trntype, "CREDIT") self.assertEqual(line.date, datetime.datetime(2013, 7, 4, 0, 0)) self.assertEqual(line.id, generate_transaction_id(line)) +class TestRaiffeisenMeinElbaCsvParser(unittest.TestCase): + """Unit tests for RaiffeisenCsvParser for Mein ELBA.""" + + def setUp(self): + csvfile = os.path.join( + os.path.dirname(__file__), 'samples', 'raiffeisen-meinelba.csv') + with open(csvfile, 'r', encoding='utf8-sig') as fin: + self.statement = RaiffeisenCsvParser(fin).parse() + + def test_statement_properties(self): + self.assertEqual(len(self.statement.lines), 4) + self.assertEqual(self.statement.start_balance, 0.0) + self.assertAlmostEqual(self.statement.end_balance, Decimal('-414.15')) + self.assertEqual(self.statement.currency, "EUR") + self.assertEqual( + self.statement.start_date, datetime.datetime(2020, 8, 1, 0, 0)) + self.assertEqual( + self.statement.end_date, datetime.datetime(2020, 8, 13, 0, 0)) + + def test_line0_payment(self): + line = self.statement.lines[0] + self.assertEqual(line.amount, Decimal('-12.84')) + self.assertEqual(line.memo, "123") + self.assertEqual(line.trntype, "DEBIT") + self.assertEqual(line.date, datetime.datetime(2020, 8, 1, 0, 0)) + self.assertEqual(line.id, generate_transaction_id(line)) + + def test_line0_interest_paid(self): + line = self.statement.lines[1] + self.assertEqual(line.amount, Decimal('-121.31')) + self.assertEqual(line.memo, "UEB Rate/Zinsen") + self.assertEqual(line.trntype, "DEBIT") + self.assertEqual(line.date, datetime.datetime(2020, 8, 5, 0, 0)) + self.assertEqual(line.id, generate_transaction_id(line)) + + def test_line1_online_banking_payment(self): + line = self.statement.lines[2] + self.assertEqual(line.amount, Decimal('-400.00')) + self.assertEqual(line.memo, "Übertrag") + self.assertEqual(line.trntype, "DEBIT") + self.assertEqual(line.date, datetime.datetime(2020, 8, 5, 0, 0)) + self.assertEqual(line.id, generate_transaction_id(line)) + + def test_line2_incoming(self): + line = self.statement.lines[3] + self.assertEqual(line.amount, Decimal('120')) + self.assertEqual(line.memo, "Gutschrifts Nr. 123 vom 01.08.2020") + self.assertEqual(line.trntype, "CREDIT") + self.assertEqual(line.date, datetime.datetime(2020, 8, 13, 0, 0)) + self.assertEqual(line.id, generate_transaction_id(line)) + + # vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4 smartindent autoindent