Browse Source

[MIG] account_bank_statement_import_qif: Migration to 9.0

* Manifest reformat
* Added license and contributors
* Tests improved
* Added matching partners
* Added supported format in view
pull/129/head
Pedro M. Baeza 9 years ago
parent
commit
e4ec02ecac
  1. 52
      account_bank_statement_import_qif/README.rst
  2. 4
      account_bank_statement_import_qif/__init__.py
  3. 20
      account_bank_statement_import_qif/__openerp__.py
  4. 49
      account_bank_statement_import_qif/i18n/account_bank_statement_import_qif.pot
  5. 4
      account_bank_statement_import_qif/i18n/es.po
  6. 40
      account_bank_statement_import_qif/tests/test_import_bank_statement.py
  7. 0
      account_bank_statement_import_qif/tests/test_qif.qif
  8. 4
      account_bank_statement_import_qif/wizards/__init__.py
  9. 54
      account_bank_statement_import_qif/wizards/account_bank_statement_import_qif.py
  10. 14
      account_bank_statement_import_qif/wizards/account_bank_statement_import_qif_view.xml

52
account_bank_statement_import_qif/README.rst

@ -1,35 +1,48 @@
.. 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
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
:alt: License: AGPL-3
Module to import QIF bank statements.
=====================================
==========================
Import QIF bank statements
==========================
This module allows you to import the machine readable QIF Files in Odoo: they are parsed and stored in human readable format in
This module allows you to import the machine readable QIF Files in Odoo: they
are parsed and stored in human readable format in
Accounting \ Bank and Cash \ Bank Statements. Accounting \ Bank and Cash \ Bank Statements.
Important Note Important Note
---------------
Because of the QIF format limitation, we cannot ensure the same transactions aren't imported several times or handle multicurrency.
Whenever possible, you should use a more appropriate file format like OFX.
--------------
Because of the QIF format limitation, we cannot ensure the same transactions
aren't imported several times or handle multicurrency. Whenever possible, you
should use a more appropriate file format like OFX.
The module has been initiated by a backport of the new framework developed
by Odoo for V9 at its early stage. It's no more kept in sync with the V9 since
it has reach a stage where maintaining a pure backport of 9.0 in 8.0 is not
feasible anymore
The module was initiated as a backport of the new framework developed
by Odoo for V9 at its early stage. As Odoo has relicensed this module as
private inside its Odoo enterprise layer, now this one is maintained from the
original AGPL code.
Known issues / Roadmap
======================
Usage
=====
* None
To use this module, you need to:
#. Go to *Accounting* dashboard.
#. Click on *Import statement* from any of the bank journals.
#. Select a QIF file.
#. Press *Import*.
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
:alt: Try me on Runbot
:target: https://runbot.odoo-community.org/runbot/174/9.0
Bug Tracker Bug Tracker
=========== ===========
Bugs are tracked on `GitHub Issues <https://github.com/OCA/bank-statement-import/issues>`_.
Bugs are tracked on
`GitHub Issues <https://github.com/OCA/bank-statement-import/issues>`_.
In case of trouble, please check there if your issue has already been reported. In case of trouble, please check there if your issue has already been reported.
If you spotted it first, help us smashing it by providing a detailed and welcomed feedback
`here <https://github.com/OCA/bank-statement-import/issues/new?body=module:%20account_bank_statement_import_ofx%0Aversion:%208.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
If you spotted it first, help us smashing it by providing a detailed and
welcomed feedback.
Credits Credits
======= =======
@ -41,6 +54,7 @@ Contributors
* 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>
* Pedro M. Baeza <pedro.baeza@tecnativa.com>
Maintainer Maintainer
---------- ----------
@ -55,4 +69,4 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose
mission is to support the collaborative development of Odoo features and mission is to support the collaborative development of Odoo features and
promote its widespread use. promote its widespread use.
To contribute to this module, please visit http://odoo-community.org.
To contribute to this module, please visit https://odoo-community.org.

4
account_bank_statement_import_qif/__init__.py

@ -1,2 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from . import account_bank_statement_import_qif
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import wizards

20
account_bank_statement_import_qif/__openerp__.py

@ -1,16 +1,24 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2015 Odoo S. A.
# Copyright 2015 Laurent Mignon <laurent.mignon@acsone.eu>
# Copyright 2015 Ronald Portier <rportier@therp.nl>
# Copyright 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
{ {
'name': 'Import QIF Bank Statement',
'category': 'Banking addons',
'version': '8.0.1.0.0',
'name': 'Import QIF Bank Statements',
'category': 'Accounting',
'version': '9.0.1.0.0',
'author': 'OpenERP SA,' 'author': 'OpenERP SA,'
'Tecnativa,'
'Odoo Community Association (OCA)', 'Odoo Community Association (OCA)',
'website': 'https://github.com/OCA/bank-statement-import', 'website': 'https://github.com/OCA/bank-statement-import',
'images': [],
'depends': [ 'depends': [
'account_bank_statement_import'
'account_bank_statement_import',
],
'data': [
'wizards/account_bank_statement_import_qif_view.xml',
], ],
'auto_install': False,
'installable': True, 'installable': True,
'license': 'AGPL-3',
} }

49
account_bank_statement_import_qif/i18n/account_bank_statement_import_qif.pot

@ -1,49 +0,0 @@
# Translation of Odoo Server.
# This file contains the translation of the following modules:
# * account_bank_statement_import_qif
#
msgid ""
msgstr ""
"Project-Id-Version: Odoo Server 8.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2015-06-08 12:01+0000\n"
"PO-Revision-Date: 2015-06-08 12:01+0000\n"
"Last-Translator: <>\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: \n"
"Plural-Forms: \n"
#. module: account_bank_statement_import_qif
#: help:account.bank.statement.import,journal_id:0
msgid "Accounting journal related to the bank statement you're importing. It has be be manually chosen for statement formats which doesn't allow automatic journal detection (QIF for example)."
msgstr ""
#. module: account_bank_statement_import_qif
#: code:addons/account_bank_statement_import_qif/account_bank_statement_import_qif.py:54
#, python-format
msgid "Could not decipher the QIF file."
msgstr ""
#. module: account_bank_statement_import_qif
#: field:account.bank.statement.import,hide_journal_field:0
msgid "Hide the journal field in the view"
msgstr ""
#. module: account_bank_statement_import_qif
#: model:ir.model,name:account_bank_statement_import_qif.model_account_bank_statement_import
msgid "Import Bank Statement"
msgstr ""
#. module: account_bank_statement_import_qif
#: field:account.bank.statement.import,journal_id:0
msgid "Journal"
msgstr ""
#. module: account_bank_statement_import_qif
#: code:addons/account_bank_statement_import_qif/account_bank_statement_import_qif.py:98
#, python-format
msgid "This file is either not a bank statement or is not correctly formed."
msgstr ""

4
account_bank_statement_import_qif/i18n/es.po

@ -21,7 +21,7 @@ msgstr ""
#: code:addons/account_bank_statement_import_qif/account_bank_statement_import_qif.py:39 #: code:addons/account_bank_statement_import_qif/account_bank_statement_import_qif.py:39
#, python-format #, python-format
msgid "Could not decipher the QIF file." msgid "Could not decipher the QIF file."
msgstr ""
msgstr "No se puede descifrar el archivo QIF."
#. module: account_bank_statement_import_qif #. module: account_bank_statement_import_qif
#: model:ir.model,name:account_bank_statement_import_qif.model_account_bank_statement_import #: model:ir.model,name:account_bank_statement_import_qif.model_account_bank_statement_import
@ -32,4 +32,4 @@ msgstr "Importar extracto bancario"
#: code:addons/account_bank_statement_import_qif/account_bank_statement_import_qif.py:83 #: code:addons/account_bank_statement_import_qif/account_bank_statement_import_qif.py:83
#, python-format #, python-format
msgid "This file is either not a bank statement or is not correctly formed." msgid "This file is either not a bank statement or is not correctly formed."
msgstr ""
msgstr "Este archivo no es un extracto bancario o no está correctamente formado."

40
account_bank_statement_import_qif/tests/test_import_bank_statement.py

@ -1,4 +1,9 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2015 Odoo S. A.
# Copyright 2015 Laurent Mignon <laurent.mignon@acsone.eu>
# Copyright 2015 Ronald Portier <rportier@therp.nl>
# Copyright 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from openerp.tests.common import TransactionCase from openerp.tests.common import TransactionCase
from openerp.modules.module import get_module_resource from openerp.modules.module import get_module_resource
@ -13,17 +18,32 @@ class TestQifFile(TransactionCase):
super(TestQifFile, self).setUp() super(TestQifFile, self).setUp()
self.statement_import_model = self.env['account.bank.statement.import'] self.statement_import_model = self.env['account.bank.statement.import']
self.statement_line_model = self.env['account.bank.statement.line'] self.statement_line_model = self.env['account.bank.statement.line']
self.journal = self.env['account.journal'].create({
'name': 'Test bank journal',
'code': 'TEST',
'type': 'bank',
})
self.partner = self.env['res.partner'].create({
# Different case for trying insensitive case search
'name': 'EPIC Technologies',
})
def test_qif_file_import(self): def test_qif_file_import(self):
from openerp.tools import float_compare
qif_file_path = get_module_resource( qif_file_path = get_module_resource(
'account_bank_statement_import_qif',
'test_qif_file', 'test_qif.qif')
'account_bank_statement_import_qif', 'tests', 'test_qif.qif',
)
qif_file = open(qif_file_path, 'rb').read().encode('base64') qif_file = open(qif_file_path, 'rb').read().encode('base64')
bank_statement_improt = self.statement_import_model.with_context(
journal_id=self.ref('account.bank_journal')).create(
dict(data_file=qif_file))
bank_statement_improt.import_file()
bank_statement = self.statement_line_model.search(
[('name', '=', 'YOUR LOCAL SUPERMARKET')], limit=1)[0].statement_id
assert float_compare(bank_statement.balance_end_real, -1896.09, 2) == 0
wizard = self.statement_import_model.with_context(
journal_id=self.journal.id
).create(
dict(data_file=qif_file)
)
wizard.import_file()
statement = self.statement_line_model.search(
[('name', '=', 'YOUR LOCAL SUPERMARKET')], limit=1,
)[0].statement_id
self.assertAlmostEqual(statement.balance_end_real, -1896.09, 2)
line = self.statement_line_model.search(
[('name', '=', 'Epic Technologies')], limit=1,
)
self.assertEqual(line.partner_id, self.partner)

0
account_bank_statement_import_qif/test_qif_file/test_qif.qif → account_bank_statement_import_qif/tests/test_qif.qif

4
account_bank_statement_import_qif/wizards/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from . import account_bank_statement_import_qif

54
account_bank_statement_import_qif/account_bank_statement_import_qif.py → account_bank_statement_import_qif/wizards/account_bank_statement_import_qif.py

@ -1,20 +1,21 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright 2015 Odoo S. A.
# Copyright 2015 Laurent Mignon <laurent.mignon@acsone.eu>
# Copyright 2015 Ronald Portier <rportier@therp.nl>
# Copyright 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import dateutil.parser import dateutil.parser
import StringIO import StringIO
from openerp.tools.translate import _ from openerp.tools.translate import _
from openerp import api, models from openerp import api, models
from openerp.exceptions import Warning
from openerp.exceptions import UserError
class AccountBankStatementImport(models.TransientModel): class AccountBankStatementImport(models.TransientModel):
_inherit = "account.bank.statement.import" _inherit = "account.bank.statement.import"
@api.model
def _get_hide_journal_field(self):
return self.env.context.get('journal_id') and True
@api.model @api.model
def _check_qif(self, data_file): def _check_qif(self, data_file):
return data_file.strip().startswith('!Type:') return data_file.strip().startswith('!Type:')
@ -24,7 +25,6 @@ class AccountBankStatementImport(models.TransientModel):
if not self._check_qif(data_file): if not self._check_qif(data_file):
return super(AccountBankStatementImport, self)._parse_file( return super(AccountBankStatementImport, self)._parse_file(
data_file) data_file)
try: try:
file_data = "" file_data = ""
for line in StringIO.StringIO(data_file).readlines(): for line in StringIO.StringIO(data_file).readlines():
@ -36,7 +36,7 @@ class AccountBankStatementImport(models.TransientModel):
header = data_list[0].strip() header = data_list[0].strip()
header = header.split(":")[1] header = header.split(":")[1]
except: except:
raise Warning(_('Could not decipher the QIF file.'))
raise UserError(_('Could not decipher the QIF file.'))
transactions = [] transactions = []
vals_line = {} vals_line = {}
total = 0 total = 0
@ -55,19 +55,10 @@ class AccountBankStatementImport(models.TransientModel):
elif line[0] == 'N': # Check number elif line[0] == 'N': # Check number
vals_line['ref'] = line[1:] vals_line['ref'] = line[1:]
elif line[0] == 'P': # Payee elif line[0] == 'P': # Payee
vals_line['name'] = ('name' in vals_line and
line[1:] + ': ' + vals_line['name'] or
line[1:])
# Since QIF doesn't provide account numbers, we'll have to
# find res.partner and res.partner.bank here
# (normal behavious is to provide 'account_number', which
# the generic module uses to find partner/bank)
banks = self.env['res.partner.bank'].search(
[('owner_name', '=', line[1:])], limit=1)
if banks:
bank_account = banks[0]
vals_line['bank_account_id'] = bank_account.id
vals_line['partner_id'] = bank_account.partner_id.id
vals_line['name'] = (
'name' in vals_line and
line[1:] + ': ' + vals_line['name'] or line[1:]
)
elif line[0] == 'M': # Memo elif line[0] == 'M': # Memo
vals_line['name'] = ('name' in vals_line and vals_line['name'] = ('name' in vals_line and
vals_line['name'] + ': ' + line[1:] or vals_line['name'] + ': ' + line[1:] or
@ -80,11 +71,28 @@ class AccountBankStatementImport(models.TransientModel):
else: else:
pass pass
else: else:
raise Warning(_('This file is either not a bank statement or is '
'not correctly formed.'))
raise UserError(_('This file is either not a bank statement or is '
'not correctly formed.'))
vals_bank_statement.update({ vals_bank_statement.update({
'balance_end_real': total, 'balance_end_real': total,
'transactions': transactions 'transactions': transactions
}) })
return None, None, [vals_bank_statement] return None, None, [vals_bank_statement]
def _complete_stmts_vals(self, stmt_vals, journal_id, account_number):
"""Match partner_id if hasn't been deducted yet."""
res = super(AccountBankStatementImport, self)._complete_stmts_vals(
stmt_vals, journal_id, account_number,
)
# Since QIF doesn't provide account numbers (normal behaviour is to
# provide 'account_number', which the generic module uses to find
# the partner), we have to find res.partner through the name
partner_obj = self.env['res.partner']
for statement in res:
for line_vals in statement['transactions']:
if not line_vals.get('partner_id') and line_vals.get('name'):
partner = partner_obj.search(
[('name', 'ilike', line_vals['name'])], limit=1,
)
line_vals['partner_id'] = partner.id
return res

14
account_bank_statement_import_qif/wizards/account_bank_statement_import_qif_view.xml

@ -0,0 +1,14 @@
<?xml version="1.0" ?>
<odoo>
<record id="account_bank_statement_import_view" 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>Quicken Interchange Format (.qif)</li>
</xpath>
</field>
</record>
</odoo>
Loading…
Cancel
Save