Files

74 lines
2.5 KiB
Python

import datetime
import re
import ofxparse
class OfxParser(ofxparse.OfxParser):
""" This class monkey-patches the ofxparse library in order to fix the following known bug: ',' is a valid
decimal separator for amounts, as we can encounter in ofx files made by european banks.
"""
@classmethod
def decimal_separator_cleanup(cls, tag):
if hasattr(tag, "contents"):
tag.string = tag.contents[0].replace(',', '.')
@classmethod
def parseStatement(cls, stmt_ofx):
ledger_bal_tag = stmt_ofx.find('ledgerbal')
if hasattr(ledger_bal_tag, "contents"):
balamt_tag = ledger_bal_tag.find('balamt')
cls.decimal_separator_cleanup(balamt_tag)
avail_bal_tag = stmt_ofx.find('availbal')
if hasattr(avail_bal_tag, "contents"):
balamt_tag = avail_bal_tag.find('balamt')
cls.decimal_separator_cleanup(balamt_tag)
return super().parseStatement(stmt_ofx)
@classmethod
def parseTransaction(cls, txn_ofx):
amt_tag = txn_ofx.find('trnamt')
cls.decimal_separator_cleanup(amt_tag)
return super().parseTransaction(txn_ofx)
@classmethod
def parseInvestmentPosition(cls, ofx):
tag = ofx.find('units')
cls.decimal_separator_cleanup(tag)
tag = ofx.find('unitprice')
cls.decimal_separator_cleanup(tag)
return super().parseInvestmentPosition(ofx)
@classmethod
def parseInvestmentTransaction(cls, ofx):
tag = ofx.find('units')
cls.decimal_separator_cleanup(tag)
tag = ofx.find('unitprice')
cls.decimal_separator_cleanup(tag)
return super().parseInvestmentTransaction(ofx)
@classmethod
def parseOfxDateTime(cls, ofxDateTime):
res = re.search(r"^[0-9]*\.([0-9]{0,5})", ofxDateTime)
if res:
msec = datetime.timedelta(seconds=float("0." + res.group(1)))
else:
msec = datetime.timedelta(seconds=0)
# Some banks seem to return some OFX dates as YYYY-MM-DD; so we remove
# the '-' characters to support them as well
ofxDateTime = ofxDateTime.replace('-', '')
try:
local_date = datetime.datetime.strptime(
ofxDateTime[:14], '%Y%m%d%H%M%S'
)
return local_date + msec
except Exception: # noqa: BLE001
if not ofxDateTime or ofxDateTime[:8] == "00000000":
return None
return datetime.datetime.strptime(
ofxDateTime[:8], '%Y%m%d') + msec