arrobalytics / django-ledger

Django Ledger is a double entry accounting system built on the Django Web Framework.
https://www.djangoledger.com
GNU General Public License v3.0
917 stars 215 forks source link

Support variations in OFX files provided by banks #208

Closed tolland closed 1 month ago

tolland commented 3 months ago

Is your feature request related to a problem? Please describe. I have tested master branch with a variety of OFX files that I obtained by downloading from various UK banks. I observe failures due to missing fields.

Describe the solution you'd like

  1. Support for a variety of OFX formats in the wild
  2. test cases with OFX examples
  3. list of bank formats supported with ofx samples

Describe alternatives you've considered Could look at implementing something like nordigen API for bank feeds

Additional context

The current behaviour is that the import OFX file dialog doesn't know to which "bank account" it should be applied to. I checked other systems and they trigger the import from the bank account itself. This helps because you can then ignore the header meta data, and just assume the statement lines apply to this specific account.

tolland commented 3 months ago

This is one example from Nat West business banking in the uk

OFXHEADER:100
DATA:OFXSGML
VERSION:102
SECURITY:NONE
ENCODING:USASCII
CHARSET:1252
COMPRESSION:NONE
OLDFILEUID:NONE
NEWFILEUID:NONE
<OFX>
    <SIGNONMSGSRSV1>
        <SONRS>
            <STATUS>
                <CODE>0</CODE>
                <SEVERITY>INFO</SEVERITY>
            </STATUS>
            <DTSERVER>20240515095005</DTSERVER>
            <LANGUAGE>ENG</LANGUAGE>
            <INTU.BID>00123</INTU.BID>
        </SONRS>
    </SIGNONMSGSRSV1>
    <BANKMSGSRSV1>
        <STMTTRNRS>
            <TRNUID>1</TRNUID>
            <STATUS>
                <CODE>0</CODE>
                <SEVERITY>INFO</SEVERITY>
            </STATUS>
            <STMTRS>
                <CURDEF>GBP</CURDEF>
                <BANKACCTFROM>
                    <BANKID>112233</BANKID>
                    <ACCTID>123456789</ACCTID>
                    <ACCTTYPE>SAVINGS</ACCTTYPE>
                </BANKACCTFROM>
                <BANKTRANLIST>
                    <DTSTART>20231030</DTSTART>
                    <DTEND>20240430</DTEND>
                    <STMTTRN>
                        <TRNTYPE>XFER</TRNTYPE>
                        <DTPOSTED>20231030</DTPOSTED>
                        <TRNAMT>100000.00</TRNAMT>
                        <FITID>202310300001</FITID>
                        <NAME>From A/C 87654321</NAME>
                        <MEMO>ACME LTD</MEMO>
                    </STMTTRN>
                </BANKTRANLIST>
                <LEDGERBAL>
                    <BALAMT>123456.49</BALAMT>
                    <DTASOF>20240430</DTASOF>
                </LEDGERBAL>
                <AVAILBAL>
                    <BALAMT>0.00</BALAMT>
                    <DTASOF>20240514</DTASOF>
                </AVAILBAL>
            </STMTRS>
        </STMTTRNRS>
    </BANKMSGSRSV1>
</OFX>

fails like so:

AttributeError at /data-import/test-test-s1mnem02/import-ofx/

'OFX' object has no attribute 'org'

Request Method:     POST
Request URL:    http://127.0.0.1:9971/data-import/test-test-s1mnem02/import-ofx/
Django Version:     4.2.11
Exception Type:     AttributeError
Exception Value:    

'OFX' object has no attribute 'org'

Exception Location:     /home/user1/git/django-ledger/.venv/lib64/python3.12/site-packages/ofxtools/models/base.py, line 549, in __getattr__
Raised during:  django_ledger.views.data_import.ImportJobModelCreateView
Python Executable:  /home/user1/git/django-ledger/.venv/bin/python
Python Version:     3.12.3
Python Path:    

['/home/user1/git/django-ledger',
 '/usr/lib64/python312.zip',
 '/usr/lib64/python3.12',
 '/usr/lib64/python3.12/lib-dynload',
 '/home/tomhodder/git/django-ledger/.venv/lib64/python3.12/site-packages',
 '/home/tomhodder/git/django-ledger/.venv/lib/python3.12/site-packages']

Server time:    Sat, 25 May 2024 11:52:27 -0400
tolland commented 3 months ago

apparently are extended tags: https://github.com/csingley/ofxtools/blob/6ad692e386e0cb82d5903682d89c18be00742c29/ofxtools/models/base.py#L317