DrCr/drcr/statements/importers/ofx1.py

58 lines
2.0 KiB
Python

# DrCr: Web-based double-entry bookkeeping framework
# Copyright (C) 2022–2024 Lee Yingtong Li (RunasSudo)
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import lxml.etree as ET
from ..models import StatementLine, reporting_commodity
from datetime import datetime
from io import StringIO
def import_ofx1(file):
raw_ofx = file.read().decode('utf-8')
# Convert OFX header to SGML and parse
raw_payload = raw_ofx[raw_ofx.index('<OFX>'):]
sgml_input = StringIO(raw_payload.replace('&', '&amp;'))
try:
tree = ET.parse(sgml_input, ET.HTMLParser())
except Exception as ex:
raise ex
root = tree.getroot()
# Read transactions
lines = [] # Do first pass to catch "extra description lines"
for transaction in root.find('.//banktranlist').findall('.//stmttrn'):
date = transaction.find('.//dtposted').text
date = date[0:4] + '-' + date[4:6] + '-' + date[6:8]
description = transaction.find('.//memo').text.strip()
amount = transaction.find('.//trnamt').text.strip()
lines.append([date, description, amount, []])
imported_statement_lines = []
# Import
for date, description, amount, notes in lines:
imported_statement_lines.append(StatementLine(
dt=datetime.strptime(date, '%Y-%m-%d'),
description=description,
quantity=round(float(amount)*100),
commodity=reporting_commodity()
))
return imported_statement_lines