File: citadeleLV.py

package info (click to toggle)
ofxstatement-plugins 20161204
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 3,160 kB
  • ctags: 1,619
  • sloc: python: 4,374; xml: 292; makefile: 103
file content (106 lines) | stat: -rw-r--r-- 3,981 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
"""Parser implementation for Citadele generated statement reports"""

import re
from xml.etree import ElementTree

from ofxstatement.parser import StatementParser
from ofxstatement.plugin import Plugin
from ofxstatement.statement import Statement, StatementLine

#CARD_PURCHASE_RE = re.compile(r".* Pirkums - .*? - par (\d\d\/\d\d\/\d\d\d\d)", re.U | re.M)

class CitadeleLVStatementParser(StatementParser):
    date_format = "%Y-%m-%d"

    statement = None
    fin = None  # file input stream

    def __init__(self, fin):
        self.statement = Statement()
        self.fin = fin

    def split_records(self):
        xml = ElementTree.parse(self.fin)
        xml = xml.getroot()

        namespaces = {'ns': xml.tag[1:].partition("}")[0]}
        statement = xml.find('ns:Statement', namespaces=namespaces)

        period = statement.find('ns:Period', namespaces=namespaces)
        self.statement.start_date = self.parse_datetime(period.find('ns:StartDate', namespaces=namespaces).text)
        self.statement.end_date = self.parse_datetime(period.find('ns:EndDate', namespaces=namespaces).text)

        account = statement.find('ns:AccountSet', namespaces=namespaces)
        if not self.statement.account_id:
            self.statement.account_id = account.find('ns:AccNo', namespaces=namespaces).text

        transactions = account.find('ns:CcyStmt', namespaces=namespaces)
        self.statement.start_balance = self.parse_float(transactions.find('ns:OpenBal', namespaces=namespaces).text)

        all_transactions = transactions.findall('ns:TrxSet', namespaces=namespaces)

        return all_transactions

    def parse_record(self, line):
        # Namespace stuff
        namespaces = {'ns': line.tag[1:].partition("}")[0]}

        # Get all fields
        type_code = line.find('ns:TypeCode', namespaces=namespaces).text
        date = line.find('ns:BookDate', namespaces=namespaces).text
        c_or_d = line.find('ns:CorD', namespaces=namespaces).text
        amount = line.find('ns:AccAmt', namespaces=namespaces).text
        id = line.find('ns:BankRef', namespaces=namespaces).text
        note = line.find('ns:PmtInfo', namespaces=namespaces).text

        # Payee name
        payee_name = None
        payee = line.find('ns:CPartySet', namespaces=namespaces)
        if payee:
            payee_account = payee.find('ns:AccHolder', namespaces=namespaces)
            if payee_account:
                payee_name = payee_account.find('ns:Name', namespaces=namespaces).text

        # Create statement line
        stmt_line = StatementLine(id, self.parse_datetime(date), note, self.parse_float(amount))
        stmt_line.payee = payee_name

        # Credit & Debit stuff
        stmt_line.trntype = "DEP"
        if c_or_d == 'D':
            stmt_line.amount = -stmt_line.amount
            stmt_line.trntype = "DEBIT"

        # Various types
        if type_code == 'CHOU':
            stmt_line.trntype = "ATM"
        elif type_code == 'MEMD':
            stmt_line.trntype = "SRVCHG"
        elif type_code == 'OUTP':
            stmt_line.trntype = "PAYMENT"
        elif type_code == 'INP':
            stmt_line.trntype = "XFER"

#        # Check if paid by card
#         m = CARD_PURCHASE_RE.match(stmt_line.memo)
#         if m:
#             # this is an electronic purchase. extract some useful
#             # information from memo field
#             date = m.group(1).split('/')
#             date = '%s-%s-%s' % (date[2], date[1], date[0])
#             stmt_line.date_user = self.parse_datetime(date)

        print(stmt_line, stmt_line.trntype)
        return stmt_line

    def parse_float(self, value):
        return value if isinstance(value, float) else float(value.replace(',', '.'))


class CitadeleLVPlugin(Plugin):
    """Latvian Citadele CSV"""

    def get_parser(self, fin):
        parser = CitadeleLVStatementParser(fin)
        parser.statement.currency = self.settings.get('currency', 'EUR')
        return parser