mirror of
https://github.com/OCA/bank-statement-import.git
synced 2025-01-20 12:37:43 +02:00
[REF] OCA convention;
[ADD] patch ofx parser to make this module work with some european bank like credit cooperatif; [IMP] wizard view to display OFX implementation;
This commit is contained in:
committed by
Alexis de Lattre
parent
cdb376b52c
commit
c9fe5cb455
@@ -1,6 +1,7 @@
|
||||
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
|
||||
:alt: License: AGPL-3
|
||||
|
||||
=========================
|
||||
Import OFX Bank Statement
|
||||
=========================
|
||||
|
||||
@@ -22,6 +23,21 @@ The module requires one additional python lib:
|
||||
|
||||
* `ofxparse <http://pypi.python.org/pypi/ofxparse>`_
|
||||
|
||||
Technical Note
|
||||
==============
|
||||
|
||||
this module is based on ofxparse python lib and overload some of its functions.
|
||||
|
||||
* For the time being the default ofxparse lib available with
|
||||
'pip install ofxparse' do not manage correctly european amount that are
|
||||
written with ',' and not with '.'. (For exemple, The Credit Cooperatif
|
||||
French Bank provides OFX 1.0 with amounts written with coma)
|
||||
|
||||
April, 27 2016: this problem has been fixed here:
|
||||
https://github.com/jseutter/ofxparse/commit/283f89c3246ed3fedccc3ef5c96078b7d5b94579
|
||||
but it is not available in the pip lib for the time being.
|
||||
|
||||
|
||||
Known issues / Roadmap
|
||||
======================
|
||||
|
||||
@@ -40,12 +56,13 @@ Credits
|
||||
=======
|
||||
|
||||
Contributors
|
||||
------------
|
||||
------------
|
||||
|
||||
* Odoo SA
|
||||
* Odoo SA
|
||||
* Alexis de Lattre <alexis@via.ecp.fr>
|
||||
* Laurent Mignon <laurent.mignon@acsone.eu>
|
||||
* Ronald Portier <rportier@therp.nl>
|
||||
* Sylvain LE GAL <https://twitter.com/legalsylvain>
|
||||
|
||||
Maintainer
|
||||
----------
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
|
||||
from . import account_bank_statement_import_ofx
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import models
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# -*- coding: utf-8 -*-
|
||||
{
|
||||
'name': 'Import OFX Bank Statement',
|
||||
'category': 'Banking addons',
|
||||
'version': '8.0.1.0.0',
|
||||
'version': '9.0.0.0.0',
|
||||
'license': 'AGPL-3',
|
||||
'author': 'OpenERP SA,'
|
||||
'La Louve,'
|
||||
'GRAP,'
|
||||
'Odoo Community Association (OCA)',
|
||||
'website': 'https://github.com/OCA/bank-statement-import',
|
||||
'website': 'https://odoo-community.org/',
|
||||
'depends': [
|
||||
'account_bank_statement_import'
|
||||
'l10n_generic_coa',
|
||||
'account_bank_statement_import',
|
||||
],
|
||||
'data': [
|
||||
'views/view_account_bank_statement_import.xml',
|
||||
],
|
||||
'demo': [
|
||||
'demo/demo_data.xml',
|
||||
|
||||
@@ -1,27 +1,23 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<odoo>
|
||||
|
||||
<record id="ofx_bank_journal" model="account.journal">
|
||||
<field name="name">Bank Journal - (test ofx)</field>
|
||||
<field name="code">TBNKOFX</field>
|
||||
<field name="type">bank</field>
|
||||
<field name="sequence_id" ref="account.sequence_bank_journal"/>
|
||||
<field name="default_debit_account_id" ref="account.usd_bnk"/>
|
||||
<field name="default_credit_account_id" ref="account.usd_bnk"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="currency" ref="base.USD"/>
|
||||
</record>
|
||||
<record id="ofx_sequence" model="ir.sequence">
|
||||
<field name="name">Bank Journal - (test ofx)</field>
|
||||
<field name="prefix">OFX/%(range_year)s/</field>
|
||||
<field name="implementation">no_gap</field>
|
||||
<field name="padding">4</field>
|
||||
<field name="use_date_range">1</field>
|
||||
</record>
|
||||
|
||||
<record id="ofx_company_bank" model="res.partner.bank">
|
||||
<field name="owner_name">Your Company</field>
|
||||
<field name="acc_number">123456</field>
|
||||
<field name="partner_id" ref="base.partner_root"></field>
|
||||
<field name="company_id" ref="base.main_company"></field>
|
||||
<field name="journal_id" ref="ofx_bank_journal"></field>
|
||||
<field name="state">bank</field>
|
||||
<field name="bank" ref="base.res_bank_1"/>
|
||||
</record>
|
||||
</data>
|
||||
|
||||
</openerp>
|
||||
<record id="ofx_bank_journal" model="account.journal">
|
||||
<field name="name">Bank Journal - (test ofx)</field>
|
||||
<field name="bank_acc_number">123456</field>
|
||||
<field name="code">TBNKOFX</field>
|
||||
<field name="type">bank</field>
|
||||
<field name="sequence_id" ref="ofx_sequence"/>
|
||||
<field name="user_id" ref="base.user_root"/>
|
||||
<field name="currency_id" ref="base.USD"/>
|
||||
</record>
|
||||
|
||||
</odoo>
|
||||
|
||||
2
account_bank_statement_import_ofx/models/__init__.py
Normal file
2
account_bank_statement_import_ofx/models/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import account_bank_statement_import
|
||||
@@ -5,27 +5,24 @@ import StringIO
|
||||
|
||||
from openerp import api, models
|
||||
from openerp.tools.translate import _
|
||||
from openerp.exceptions import Warning
|
||||
from openerp.exceptions import Warning as UserError
|
||||
|
||||
from .ofx import OfxParser, OfxParser_ok
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from ofxparse import OfxParser as ofxparser
|
||||
except ImportError:
|
||||
_logger.warn("ofxparse not found, OFX parsing disabled.")
|
||||
ofxparser = None
|
||||
|
||||
|
||||
class AccountBankStatementImport(models.TransientModel):
|
||||
_inherit = 'account.bank.statement.import'
|
||||
|
||||
@api.model
|
||||
def _check_ofx(self, data_file):
|
||||
if ofxparser is None:
|
||||
if not OfxParser_ok:
|
||||
return False
|
||||
try:
|
||||
ofx = ofxparser.parse(StringIO.StringIO(data_file))
|
||||
except:
|
||||
ofx = OfxParser.parse(StringIO.StringIO(data_file))
|
||||
except Exception as e:
|
||||
_logger.debug(e)
|
||||
return False
|
||||
return ofx
|
||||
|
||||
@@ -64,7 +61,7 @@ class AccountBankStatementImport(models.TransientModel):
|
||||
total_amt += float(transaction.amount)
|
||||
transactions.append(vals_line)
|
||||
except Exception, e:
|
||||
raise Warning(_("The following problem occurred during import. "
|
||||
raise UserError(_("The following problem occurred during import. "
|
||||
"The file might not be valid.\n\n %s" % e.message))
|
||||
|
||||
vals_bank_statement = {
|
||||
@@ -72,7 +69,7 @@ class AccountBankStatementImport(models.TransientModel):
|
||||
'transactions': transactions,
|
||||
'balance_start': ofx.account.statement.balance,
|
||||
'balance_end_real':
|
||||
float(ofx.account.statement.balance) + total_amt,
|
||||
float(ofx.account.statement.balance) + total_amt,
|
||||
}
|
||||
return ofx.account.statement.currency, ofx.account.number, [
|
||||
vals_bank_statement]
|
||||
40
account_bank_statement_import_ofx/models/ofx.py
Normal file
40
account_bank_statement_import_ofx/models/ofx.py
Normal file
@@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
try:
|
||||
from ofxparse import OfxParser as OfxParserOriginal
|
||||
OfxParser_ok = True
|
||||
except ImportError:
|
||||
_logger.warn("ofxparse not found, OFX parsing disabled.")
|
||||
OfxParserOriginal = object
|
||||
OfxParser_ok = False
|
||||
|
||||
|
||||
class OfxParser(OfxParserOriginal):
|
||||
""" Custom changes in the OFX Parser.
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def _tagToDecimal(self, tag):
|
||||
tag.string = tag.string.replace(',', '.')
|
||||
|
||||
@classmethod
|
||||
def parseStatement(cls_, stmt_ofx):
|
||||
"""Amount with ',' replaced by '.' in the following tags :
|
||||
//LEDGERBAL/BALAMT
|
||||
"""
|
||||
ledgerbal_tag = stmt_ofx.find('ledgerbal')
|
||||
if hasattr(ledgerbal_tag, "contents"):
|
||||
cls_._tagToDecimal(ledgerbal_tag.find('balamt'))
|
||||
return super(OfxParser, cls_).parseStatement(stmt_ofx)
|
||||
|
||||
@classmethod
|
||||
def parseTransaction(cls_, txn_ofx):
|
||||
"""Amount with ',' replaced by '.' in the following tags :
|
||||
//TRNAMT
|
||||
"""
|
||||
cls_._tagToDecimal(txn_ofx.find('trnamt'))
|
||||
return super(OfxParser, cls_).parseTransaction(txn_ofx)
|
||||
@@ -1,4 +1,2 @@
|
||||
# -*- encoding: utf-8 -*-
|
||||
# noqa: This is a backport from Odoo. OCA has no control over style here.
|
||||
# flake8: noqa
|
||||
# -*- coding: utf-8 -*-
|
||||
from . import test_import_bank_statement
|
||||
|
||||
@@ -16,7 +16,7 @@ class TestOfxFile(TransactionCase):
|
||||
def test_ofx_file_import(self):
|
||||
ofx_file_path = get_module_resource(
|
||||
'account_bank_statement_import_ofx',
|
||||
'test_ofx_file', 'test_ofx.ofx')
|
||||
'tests/test_ofx_file/', 'test_ofx.ofx')
|
||||
ofx_file = open(ofx_file_path, 'rb').read().encode('base64')
|
||||
bank_statement = self.statement_import_model.create(
|
||||
dict(data_file=ofx_file))
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" ?>
|
||||
<odoo>
|
||||
<record id="view_account_bank_statement_import_form" model="ir.ui.view">
|
||||
<field name="model">account.bank.statement.import</field>
|
||||
<field name="inherit_id" ref="account_bank_statement_import.account_bank_statement_import_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="//ul[@id='statement_format']" position="inside">
|
||||
<li>Open Financial Exchange (.OFX Money)</li>
|
||||
</xpath>
|
||||
</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user