Example #1
0
    def parse_statement(self):
        statement = Statement()

        statement.account_id = self.account_id
        statement.bank_id = self.bank_id
        statement.currency = self.currency

        rows = self.sheet_rows()
        for r in rows[2:]:
            bokf_date, _, _, _, balance = r

            # first row will be our start balance & date
            first_row = (statement.start_date is
                         None) or (statement.start_balance is None)
            if first_row:
                statement.start_date = self.parse_datetime(bokf_date)
                statement.start_balance = self.parse_float(balance)

            # last row will be our end balance & date
            statement.end_balance = self.parse_float(balance)
            statement.end_date = self.parse_datetime(bokf_date)

        #
        # Use the fact that first cell contains the statement date as a suffix e.g. 'Kontoutdrag - 2018-01-04'
        #
        info_header_row = rows[0]
        m = re.match('Kontoutdrag *- *([0-9]{4}-[0-9]{2}-[0-9]{2})$',
                     info_header_row[0])
        if m:
            stmt_date, = m.groups()
            statement.end_date = self.parse_datetime(stmt_date)

        return statement
Example #2
0
    def parse_statement(self):
        statement = Statement()
        sheet = self.workbook.active

        # We need only first 3 rows here.
        rows = take(3, sheet.iter_rows())
        rows = [[c.value for c in row] for row in rows]

        assert len(rows) == 3
        header_row, account_row, footer_row = rows

        account_id, saldo, disponibelt_belopp, beviljad_kredit, _1, _2 = account_row
        statement.account_id = account_id
        statement.end_balance = atof(saldo, self.locale)
        statement.bank_id = self.bank_id
        statement.currency = self.currency_id

        for r in self.footer_regexps:
            m = re.match(r, footer_row[0])
            if m and m.groups():
                part_from, part_to = m.groups()
                statement.start_date = self.parse_datetime(part_from)
                statement.end_date = self.parse_datetime(part_to)

        return statement
Example #3
0
    def test_ofxWriter(self) -> None:

        # Create sample statement:
        statement = Statement("BID", "ACCID", "LTL")
        statement.broker_id = "BROKERID"
        statement.end_date = datetime(2021, 5, 1)

        invest_line = InvestStatementLine(
            "3",
            datetime(2021, 1, 1),
            "Sample 3",
            "BUYSTOCK",
            "BUY",
            "AAPL",
            Decimal("-416.08"),
        )
        invest_line.units = Decimal("3")
        invest_line.unit_price = Decimal("138.28")
        invest_line.fees = Decimal("1.24")
        invest_line.assert_valid()
        statement.invest_lines.append(invest_line)

        invest_line = InvestStatementLine(
            "4",
            datetime(2021, 1, 1),
            "Sample 4",
            "SELLSTOCK",
            "SELL",
            "MSFT",
            Decimal("1127.87"),
        )
        invest_line.units = Decimal("-5")
        invest_line.unit_price = Decimal("225.63")
        invest_line.fees = Decimal("0.28")
        invest_line.assert_valid()
        statement.invest_lines.append(invest_line)

        invest_line = InvestStatementLine(
            "5",
            datetime(2021, 1, 1),
            "Sample 5",
            "INCOME",
            "DIV",
            "MSFT",
            Decimal("0.79"),
        )
        invest_line.fees = Decimal("0.5")
        invest_line.assert_valid()
        statement.invest_lines.append(invest_line)

        # Create writer:
        writer = ofx.OfxWriter(statement)

        # Set the generation time so it is always predictable
        writer.genTime = datetime(2021, 5, 1, 0, 0, 0)

        assert prettyPrint(writer.toxml()) == SIMPLE_OFX
Example #4
0
    def _parse_statement(self, stmt):
        statement = Statement()
        statement.currency = self.currency

        bnk = stmt.find('./s:Acct/s:Svcr/s:FinInstnId/s:BIC', self.xmlns)
        if bnk is None:
            bnk = stmt.find('./s:Acct/s:Svcr/s:FinInstnId/s:Nm', self.xmlns)
        iban = stmt.find('./s:Acct/s:Id/s:IBAN', self.xmlns)
        other = stmt.find('./s:Acct/s:Id/s:Othr/s:Id', self.xmlns)
        ccy = stmt.find('./s:Acct/s:Ccy', self.xmlns)
        bals = stmt.findall('./s:Bal', self.xmlns)

        acctCurrency = ccy.text if ccy is not None else None
        if acctCurrency:
            statement.currency = acctCurrency
        else:
            if statement.currency is None:
                raise exceptions.ParseError(
                    0, "No account currency provided in statement. Please "
                    "specify one in configuration file (e.g. currency=EUR)")

        bal_amts = {}
        bal_dates = {}
        for bal in bals:
            cd = bal.find('./s:Tp/s:CdOrPrtry/s:Cd', self.xmlns)
            amt = bal.find('./s:Amt', self.xmlns)
            dt = bal.find('./s:Dt', self.xmlns)
            amt_ccy = amt.get('Ccy')
            # Amount currency should match with statement currency
            if amt_ccy != statement.currency:
                continue

            bal_amts[cd.text] = self._parse_amount(amt)
            bal_dates[cd.text] = self._parse_date(dt)

        if not bal_amts:
            raise exceptions.ParseError(
                0, "No statement balance found for currency '%s'. Check "
                "currency of statement file." % statement.currency)

        statement.bank_id = bnk.text if bnk is not None else None
        statement.account_id = iban.text if iban is not None else other.text
        statement.start_balance = bal_amts['OPBD']
        statement.start_date = bal_dates['OPBD']
        statement.end_balance = bal_amts['CLBD']
        statement.end_date = bal_dates['CLBD']

        self._parse_lines(stmt, statement)

        return statement