Browse Source

[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;
pull/142/head
Sylvain LE GAL 9 years ago
committed by Nicolas JEUDY
parent
commit
61810d00c1
  1. 21
      account_bank_statement_import_ofx/README.rst
  2. 5
      account_bank_statement_import_ofx/__init__.py
  3. 15
      account_bank_statement_import_ofx/__manifest__.py
  4. 42
      account_bank_statement_import_ofx/demo/demo_data.xml
  5. 2
      account_bank_statement_import_ofx/models/__init__.py
  6. 21
      account_bank_statement_import_ofx/models/account_bank_statement_import.py
  7. 40
      account_bank_statement_import_ofx/models/ofx.py
  8. 4
      account_bank_statement_import_ofx/tests/__init__.py
  9. 2
      account_bank_statement_import_ofx/tests/test_import_bank_statement.py
  10. 0
      account_bank_statement_import_ofx/tests/test_ofx_file/test_ofx.ofx
  11. 12
      account_bank_statement_import_ofx/views/view_account_bank_statement_import.xml

21
account_bank_statement_import_ofx/README.rst

@ -1,6 +1,7 @@
.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg .. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg
:alt: License: AGPL-3 :alt: License: AGPL-3
=========================
Import OFX Bank Statement Import OFX Bank Statement
========================= =========================
@ -22,6 +23,21 @@ The module requires one additional python lib:
* `ofxparse <http://pypi.python.org/pypi/ofxparse>`_ * `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 Known issues / Roadmap
====================== ======================
@ -40,12 +56,13 @@ Credits
======= =======
Contributors Contributors
------------
------------
* Odoo SA
* Odoo SA
* Alexis de Lattre <alexis@via.ecp.fr> * Alexis de Lattre <alexis@via.ecp.fr>
* Laurent Mignon <laurent.mignon@acsone.eu> * Laurent Mignon <laurent.mignon@acsone.eu>
* Ronald Portier <rportier@therp.nl> * Ronald Portier <rportier@therp.nl>
* Sylvain LE GAL <https://twitter.com/legalsylvain>
Maintainer Maintainer
---------- ----------

5
account_bank_statement_import_ofx/__init__.py

@ -1,3 +1,2 @@
# -*- encoding: utf-8 -*-
from . import account_bank_statement_import_ofx
# -*- coding: utf-8 -*-
from . import models

15
account_bank_statement_import_ofx/__manifest__.py

@ -1,13 +1,20 @@
# -*- encoding: utf-8 -*-
# -*- coding: utf-8 -*-
{ {
'name': 'Import OFX Bank Statement', 'name': 'Import OFX Bank Statement',
'category': 'Banking addons', 'category': 'Banking addons',
'version': '8.0.1.0.0',
'version': '9.0.0.0.0',
'license': 'AGPL-3',
'author': 'OpenERP SA,' 'author': 'OpenERP SA,'
'La Louve,'
'GRAP,'
'Odoo Community Association (OCA)', 'Odoo Community Association (OCA)',
'website': 'https://github.com/OCA/bank-statement-import',
'website': 'https://odoo-community.org/',
'depends': [ 'depends': [
'account_bank_statement_import'
'l10n_generic_coa',
'account_bank_statement_import',
],
'data': [
'views/view_account_bank_statement_import.xml',
], ],
'demo': [ 'demo': [
'demo/demo_data.xml', 'demo/demo_data.xml',

42
account_bank_statement_import_ofx/demo/demo_data.xml

@ -1,27 +1,23 @@
<?xml version="1.0" encoding="utf-8"?> <?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

@ -0,0 +1,2 @@
# -*- coding: utf-8 -*-
from . import account_bank_statement_import

21
account_bank_statement_import_ofx/account_bank_statement_import_ofx.py → account_bank_statement_import_ofx/models/account_bank_statement_import.py

@ -5,15 +5,11 @@ import StringIO
from openerp import api, models from openerp import api, models
from openerp.tools.translate import _ from openerp.tools.translate import _
from openerp.exceptions import Warning
from openerp.exceptions import Warning as UserError
_logger = logging.getLogger(__name__)
from .ofx import OfxParser, OfxParser_ok
try:
from ofxparse import OfxParser as ofxparser
except ImportError:
_logger.warn("ofxparse not found, OFX parsing disabled.")
ofxparser = None
_logger = logging.getLogger(__name__)
class AccountBankStatementImport(models.TransientModel): class AccountBankStatementImport(models.TransientModel):
@ -21,11 +17,12 @@ class AccountBankStatementImport(models.TransientModel):
@api.model @api.model
def _check_ofx(self, data_file): def _check_ofx(self, data_file):
if ofxparser is None:
if not OfxParser_ok:
return False return False
try: 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 False
return ofx return ofx
@ -64,7 +61,7 @@ class AccountBankStatementImport(models.TransientModel):
total_amt += float(transaction.amount) total_amt += float(transaction.amount)
transactions.append(vals_line) transactions.append(vals_line)
except Exception, e: 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)) "The file might not be valid.\n\n %s" % e.message))
vals_bank_statement = { vals_bank_statement = {
@ -72,7 +69,7 @@ class AccountBankStatementImport(models.TransientModel):
'transactions': transactions, 'transactions': transactions,
'balance_start': ofx.account.statement.balance, 'balance_start': ofx.account.statement.balance,
'balance_end_real': '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, [ return ofx.account.statement.currency, ofx.account.number, [
vals_bank_statement] vals_bank_statement]

40
account_bank_statement_import_ofx/models/ofx.py

@ -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)

4
account_bank_statement_import_ofx/tests/__init__.py

@ -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 from . import test_import_bank_statement

2
account_bank_statement_import_ofx/tests/test_import_bank_statement.py

@ -16,7 +16,7 @@ class TestOfxFile(TransactionCase):
def test_ofx_file_import(self): def test_ofx_file_import(self):
ofx_file_path = get_module_resource( ofx_file_path = get_module_resource(
'account_bank_statement_import_ofx', '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') ofx_file = open(ofx_file_path, 'rb').read().encode('base64')
bank_statement = self.statement_import_model.create( bank_statement = self.statement_import_model.create(
dict(data_file=ofx_file)) dict(data_file=ofx_file))

0
account_bank_statement_import_ofx/test_ofx_file/test_ofx.ofx → account_bank_statement_import_ofx/tests/test_ofx_file/test_ofx.ofx

12
account_bank_statement_import_ofx/views/view_account_bank_statement_import.xml

@ -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>
Loading…
Cancel
Save