Browse Source

Merge pull request #2 from NL66278/8.0_move_framework

8.0 move framework
pull/3/head
Pedro M. Baeza 10 years ago
parent
commit
ec092886a7
  1. 1
      .travis.yml
  2. 4
      account_bank_statement_import/__init__.py
  3. 27
      account_bank_statement_import/__openerp__.py
  4. 98
      account_bank_statement_import/account_bank_statement_import.py
  5. 51
      account_bank_statement_import/account_bank_statement_import_view.xml
  6. 119
      account_bank_statement_import/demo/fiscalyear_period.xml
  7. 38
      account_bank_statement_import/demo/partner_bank.xml
  8. 4
      account_bank_statement_import_ofx/__init__.py
  9. 32
      account_bank_statement_import_ofx/__openerp__.py
  10. 76
      account_bank_statement_import_ofx/account_bank_statement_import_ofx.py
  11. 100
      account_bank_statement_import_ofx/test_ofx_file/test_ofx.ofx
  12. 8
      account_bank_statement_import_ofx/tests/__init__.py
  13. 33
      account_bank_statement_import_ofx/tests/test_import_bank_statement.py
  14. 4
      account_bank_statement_import_qif/__init__.py
  15. 32
      account_bank_statement_import_qif/__openerp__.py
  16. 77
      account_bank_statement_import_qif/account_bank_statement_import_qif.py
  17. 21
      account_bank_statement_import_qif/test_qif_file/test_qif.qif
  18. 8
      account_bank_statement_import_qif/tests/__init__.py
  19. 30
      account_bank_statement_import_qif/tests/test_import_bank_statement.py

1
.travis.yml

@ -13,6 +13,7 @@ virtualenv:
install:
- git clone https://github.com/OCA/maintainer-quality-tools.git ${HOME}/maintainer-quality-tools
- export PATH=${HOME}/maintainer-quality-tools/travis:${PATH}
- pip install ofxparse
- travis_install_nightly
# example: dependency
# - git clone https://github.com/OCA/webkit-tools -b ${VERSION} $HOME/webkit-tools

4
account_bank_statement_import/__init__.py

@ -0,0 +1,4 @@
# -*- encoding: utf-8 -*-
from . import account_bank_statement_import
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

27
account_bank_statement_import/__openerp__.py

@ -0,0 +1,27 @@
# -*- encoding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
{
'name': 'Account Bank Statement Import',
'version': '1.0',
'author': 'OpenERP SA',
'depends': ['account'],
'demo': [],
'description' : """Generic Wizard to Import Bank Statements.
Includes the import of files in .OFX format
Backport from Odoo 9.0
""",
'data' : [
'account_bank_statement_import_view.xml',
],
'demo': [
'demo/fiscalyear_period.xml',
'demo/partner_bank.xml',
],
'auto_install': False,
'installable': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

98
account_bank_statement_import/account_bank_statement_import.py

@ -0,0 +1,98 @@
# -*- coding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
from openerp.osv import fields, osv
from openerp.tools.translate import _
import logging
_logger = logging.getLogger(__name__)
_IMPORT_FILE_TYPE = [('none', _('No Import Format Available'))]
def add_file_type(selection_value):
global _IMPORT_FILE_TYPE
if _IMPORT_FILE_TYPE[0][0] == 'none':
_IMPORT_FILE_TYPE = [selection_value]
else:
_IMPORT_FILE_TYPE.append(selection_value)
class account_bank_statement_import(osv.TransientModel):
_name = 'account.bank.statement.import'
_description = 'Import Bank Statement'
def _get_import_file_type(self, cr, uid, context=None):
return _IMPORT_FILE_TYPE
_columns = {
'data_file': fields.binary('Bank Statement File', required=True, help='Get you bank statements in electronic format from your bank and select them here.'),
'file_type': fields.selection(_get_import_file_type, 'File Type', required=True),
'journal_id': fields.many2one('account.journal', 'Journal', required=True, help="The journal for which the bank statements will be created"),
}
def _get_first_file_type(self, cr, uid, context=None):
return self._get_import_file_type(cr, uid, context=context)[0][0]
def _get_default_journal(self, cr, uid, context=None):
company_id = self.pool.get('res.company')._company_default_get(cr, uid, 'account.bank.statement', context=context)
journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'bank'), ('company_id', '=', company_id)], context=context)
return journal_ids and journal_ids[0] or False
_defaults = {
'file_type': _get_first_file_type,
'journal_id': _get_default_journal,
}
def _detect_partner(self, cr, uid, identifying_string, identifying_field='acc_number', context=None):
"""Try to find a bank account and its related partner for the given 'identifying_string', looking on the field 'identifying_field'.
:param identifying_string: varchar
:param identifying_field: varchar corresponding to the name of a field of res.partner.bank
:returns: tuple(ID of the bank account found or False, ID of the partner for the bank account found or False)
"""
partner_id = False
bank_account_id = False
if identifying_string:
ids = self.pool.get('res.partner.bank').search(cr, uid, [(identifying_field, '=', identifying_string)], context=context)
if ids:
bank_account_id = ids[0]
partner_id = self.pool.get('res.partner.bank').browse(cr, uid, bank_account_id, context=context).partner_id.id
else:
#create the bank account, not linked to any partner. The reconciliation will link the partner manually
#chosen at the bank statement final confirmation time.
try:
type_model, type_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'base', 'bank_normal')
type_id = self.pool.get('res.partner.bank.type').browse(cr, uid, type_id, context=context)
bank_code = type_id.code
except ValueError:
bank_code = 'bank'
acc_number = identifying_field == 'acc_number' and identifying_string or _('Undefined')
bank_account_vals = {
'acc_number': acc_number,
'state': bank_code,
}
bank_account_vals[identifying_field] = identifying_string
bank_account_id = self.pool.get('res.partner.bank').create(cr, uid, bank_account_vals, context=context)
return bank_account_id, partner_id
def import_bank_statement(self, cr, uid, bank_statement_vals=False, context=None):
""" Get a list of values to pass to the create() of account.bank.statement object, and returns a list of ID created using those values"""
statement_ids = []
for vals in bank_statement_vals:
statement_ids.append(self.pool.get('account.bank.statement').create(cr, uid, vals, context=context))
return statement_ids
def process_none(self, cr, uid, data_file, journal_id=False, context=None):
raise osv.except_osv(_('Error'), _('No available format for importing bank statement. You can install one of the file format available through the module installation.'))
def parse_file(self, cr, uid, ids, context=None):
""" Process the file chosen in the wizard and returns a list view of the imported bank statements"""
data = self.browse(cr, uid, ids[0], context=context)
vals = getattr(self, "process_%s" % data.file_type)(cr, uid, data.data_file, data.journal_id.id, context=context)
statement_ids = self.import_bank_statement(cr, uid, vals, context=context)
model, action_id = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'account', 'action_bank_statement_tree')
action = self.pool[model].read(cr, uid, action_id, context=context)
action['domain'] = "[('id', 'in', [" + ', '.join(map(str, statement_ids)) + "])]"
return action
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

51
account_bank_statement_import/account_bank_statement_import_view.xml

@ -0,0 +1,51 @@
<?xml version="1.0" ?>
<openerp>
<data>
<record id="account_bank_statement_import_view" model="ir.ui.view">
<field name="name">Import Bank Statements</field>
<field name="model">account.bank.statement.import</field>
<field name="priority">1</field>
<field name="arch" type="xml">
<form string="Import Bank Statements" version="7.0">
<group>
<group>
<field name="data_file"/>
<field name="file_type"/>
<field name="journal_id" domain="[('type', '=', 'bank')]" context="{'default_type':'bank'}"/>
</group>
<group>
<b colspan="2"> How to import your bank statement in OpenERP.</b>
<label string= "1. Go to your bank account website." colspan="2"/>
<label string= "2. Download your bank statements in the right format. (.OFX, .QIF or CODA are accepted)" colspan="2"/>
<label string= "3. Upload right here the bank statements file into OpenERP. Click Import." colspan="2"/>
</group>
</group>
<footer>
<button name="parse_file" string="_Import" type="object" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_account_bank_statement_import" model="ir.actions.act_window">
<field name="name">Import Bank Statement</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.bank.statement.import</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="view_id" ref="account_bank_statement_import_view"/>
</record>
<menuitem
parent="account.menu_finance_bank_and_cash"
id="menu_account_bank_statement_import"
action="action_account_bank_statement_import"
sequence="11"
/>
</data>
</openerp>

119
account_bank_statement_import/demo/fiscalyear_period.xml

@ -0,0 +1,119 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!--
Fiscal year
-->
<record id="data_fiscalyear_2013" model="account.fiscalyear">
<field eval="'Fiscal Year X 2013'" name="name"/>
<field eval="'FY2013'" name="code"/>
<field eval="'2013-01-01'" name="date_start"/>
<field eval="'2013-12-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<!--
Fiscal Periods 2013
-->
<record id="period_1_2013" model="account.period">
<field eval="'01/2013'" name="code"/>
<field eval="'X 01/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-01-01'" name="date_start"/>
<field eval="'2013-01-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_2_2013" model="account.period">
<field eval="'02/2013'" name="code"/>
<field eval="'X 02/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-02-01'" name="date_start"/>
<field eval="'2013-02-28'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_3_2013" model="account.period">
<field eval="'03/2013'" name="code"/>
<field eval="'X 03/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-03-01'" name="date_start"/>
<field eval="'2013-03-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_4_2013" model="account.period">
<field eval="'04/2013'" name="code"/>
<field eval="'X 04/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-04-01'" name="date_start"/>
<field eval="'2013-04-30'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_5_2013" model="account.period">
<field eval="'05/2013'" name="code"/>
<field eval="'X 05/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-05-01'" name="date_start"/>
<field eval="'2013-05-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_6_2013" model="account.period">
<field eval="'06/2013'" name="code"/>
<field eval="'X 06/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-06-01'" name="date_start"/>
<field eval="'2013-06-30'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_7_2013" model="account.period">
<field eval="'07/2013'" name="code"/>
<field eval="'X 07/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-07-01'" name="date_start"/>
<field eval="'2013-07-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_8_2013" model="account.period">
<field eval="'08/2013'" name="code"/>
<field eval="'X 08/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-08-01'" name="date_start"/>
<field eval="'2013-08-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_9_2013" model="account.period">
<field eval="'09/2013'" name="code"/>
<field eval="'X 09/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-09-01'" name="date_start"/>
<field eval="'2013-09-30'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_10_2013" model="account.period">
<field eval="'10/2013'" name="code"/>
<field eval="'X 10/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-10-01'" name="date_start"/>
<field eval="'2013-10-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_11_2013" model="account.period">
<field eval="'11/2013'" name="code"/>
<field eval="'X 11/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-11-01'" name="date_start"/>
<field eval="'2013-11-30'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
<record id="period_12_2013" model="account.period">
<field eval="'12/2013'" name="code"/>
<field eval="'X 12/2013'" name="name"/>
<field name="fiscalyear_id" ref="data_fiscalyear_2013"/>
<field eval="'2013-12-01'" name="date_start"/>
<field eval="'2013-12-31'" name="date_stop"/>
<field name="company_id" ref="base.main_company"/>
</record>
</data>
</openerp>

38
account_bank_statement_import/demo/partner_bank.xml

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<record id="ofx_partner_bank_1" model="res.partner.bank">
<field name="owner_name">Agrolait</field>
<field name="acc_number">00987654321</field>
<field name="partner_id" ref="base.res_partner_2"></field>
<field name="state">bank</field>
<field name="bank" ref="base.res_bank_1"/>
</record>
<record id="ofx_partner_bank_2" model="res.partner.bank">
<field name="owner_name">China Export</field>
<field name="acc_number">00987654322</field>
<field name="partner_id" ref="base.res_partner_3"></field>
<field name="state">bank</field>
<field name="bank" ref="base.res_bank_1"/>
</record>
<record id="qif_partner_bank_1" model="res.partner.bank">
<field name="owner_name">Delta PC</field>
<field name="acc_number">10987654320</field>
<field name="partner_id" ref="base.res_partner_4"></field>
<field name="state">bank</field>
<field name="bank" ref="base.res_bank_1"/>
</record>
<record id="qif_partner_bank_2" model="res.partner.bank">
<field name="owner_name">Epic Technologies</field>
<field name="acc_number">10987654322</field>
<field name="partner_id" ref="base.res_partner_5"></field>
<field name="state">bank</field>
<field name="bank" ref="base.res_bank_1"/>
</record>
</data>
</openerp>

4
account_bank_statement_import_ofx/__init__.py

@ -0,0 +1,4 @@
# -*- encoding: utf-8 -*-
from . import account_bank_statement_import_ofx
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

32
account_bank_statement_import_ofx/__openerp__.py

@ -0,0 +1,32 @@
# -*- encoding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
{
'name': 'Import OFX Bank Statement',
'version': '1.0',
'author': 'OpenERP SA',
'depends': ['account_bank_statement_import'],
'demo': [],
'description' : """
Module to import OFX bank statements.
======================================
This module allows you to import the machine readable OFX Files in Odoo: they are parsed and stored in human readable format in
Accounting \ Bank and Cash \ Bank Statements.
Bank Statements may be generated containing a subset of the OFX information (only those transaction lines that are required for the
creation of the Financial Accounting records).
Backported from Odoo 9.0
When testing with the provided test file, make sure the demo data from the
base account_bank_statement_import module has been imported, or manually
create periods for the year 2013.
""",
'data' : [],
'demo': [],
'auto_install': False,
'installable': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

76
account_bank_statement_import_ofx/account_bank_statement_import_ofx.py

@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
import logging
import base64
import os
from openerp.osv import osv
from openerp.tools.translate import _
_logger = logging.getLogger(__name__)
from openerp.addons.account_bank_statement_import import account_bank_statement_import as ibs
ibs.add_file_type(('ofx', 'OFX'))
try:
from ofxparse import OfxParser as ofxparser
except ImportError:
_logger.warning("OFX parser unavailable because the `ofxparse` Python library cannot be found."
"It can be downloaded and installed from `https://pypi.python.org/pypi/ofxparse`.")
ofxparser = None
class account_bank_statement_import(osv.TransientModel):
_inherit = 'account.bank.statement.import'
def process_ofx(self, cr, uid, data_file, journal_id=False, context=None):
""" Import a file in the .OFX format"""
if ofxparser is None:
raise osv.except_osv(_("Error"), _("OFX parser unavailable because the `ofxparse` Python library cannot be found."
"It can be downloaded and installed from `https://pypi.python.org/pypi/ofxparse`."))
try:
tempfile = open("temp.ofx", "w+")
tempfile.write(base64.decodestring(data_file))
tempfile.read()
pathname = os.path.dirname('temp.ofx')
path = os.path.join(os.path.abspath(pathname), 'temp.ofx')
ofx = ofxparser.parse(file(path))
except:
raise osv.except_osv(_('Import Error!'), _('Please check OFX file format is proper or not.'))
line_ids = []
total_amt = 0.00
try:
for transaction in ofx.account.statement.transactions:
bank_account_id, partner_id = self._detect_partner(cr, uid, transaction.payee, identifying_field='owner_name', context=context)
vals_line = {
'date': transaction.date,
'name': transaction.payee + ': ' + transaction.memo,
'ref': transaction.id,
'amount': transaction.amount,
'partner_id': partner_id,
'bank_account_id': bank_account_id,
}
total_amt += float(transaction.amount)
line_ids.append((0, 0, vals_line))
except Exception, e:
raise osv.except_osv(_('Error!'), _("Following problem has been occurred while importing your file, Please verify the file is proper or not.\n\n %s" % e.message))
st_start_date = ofx.account.statement.start_date or False
st_end_date = ofx.account.statement.end_date or False
period_obj = self.pool.get('account.period')
if st_end_date:
period_ids = period_obj.find(cr, uid, st_end_date, context=context)
else:
period_ids = period_obj.find(cr, uid, st_start_date, context=context)
vals_bank_statement = {
'name': ofx.account.routing_number,
'balance_start': ofx.account.statement.balance,
'balance_end_real': float(ofx.account.statement.balance) + total_amt,
'period_id': period_ids and period_ids[0] or False,
'journal_id': journal_id
}
vals_bank_statement.update({'line_ids': line_ids})
os.remove(path)
return [vals_bank_statement]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

100
account_bank_statement_import_ofx/test_ofx_file/test_ofx.ofx

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="ASCII"?>
<?OFX OFXHEADER="200" VERSION="211" SECURITY="NONE" OLDFILEUID="NONE" NEWFILEUID="NONE"?>
<OFX>
<SIGNONMSGSRSV1>
<SONRS>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<DTSERVER>20130831165153.000[-8:PST]</DTSERVER>
<LANGUAGE>ENG</LANGUAGE>
</SONRS>
</SIGNONMSGSRSV1>
<BANKMSGSRSV1>
<STMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<STMTRS>
<CURDEF>USD</CURDEF>
<BANKACCTFROM>
<BANKID>000000123</BANKID>
<ACCTID>123456</ACCTID>
<ACCTTYPE>CHECKING</ACCTTYPE>
</BANKACCTFROM>
<BANKTRANLIST>
<DTSTART>20130801</DTSTART>
<DTEND>20130831165153.000[-8:PST]</DTEND>
<STMTTRN>
<TRNTYPE>POS</TRNTYPE>
<DTPOSTED>20130824080000</DTPOSTED>
<TRNAMT>-80</TRNAMT>
<FITID>219378</FITID>
<NAME>Agrolait</NAME>
</STMTTRN>
</BANKTRANLIST>
<BANKTRANLIST>
<DTSTART>20130801</DTSTART>
<DTEND>20130831165153.000[-8:PST]</DTEND>
<STMTTRN>
<TRNTYPE>POS</TRNTYPE>
<DTPOSTED>20130824080000</DTPOSTED>
<TRNAMT>-90</TRNAMT>
<FITID>219379</FITID>
<NAME>China Export</NAME>
</STMTTRN>
</BANKTRANLIST>
<BANKTRANLIST>
<DTSTART>20130801</DTSTART>
<DTEND>20130831165153.000[-8:PST]</DTEND>
<STMTTRN>
<TRNTYPE>POS</TRNTYPE>
<DTPOSTED>20130824080000</DTPOSTED>
<TRNAMT>-100</TRNAMT>
<FITID>219380</FITID>
<NAME>Axelor Scuba</NAME>
</STMTTRN>
</BANKTRANLIST>
<BANKTRANLIST>
<DTSTART>20130801</DTSTART>
<DTEND>20130831165153.000[-8:PST]</DTEND>
<STMTTRN>
<TRNTYPE>POS</TRNTYPE>
<DTPOSTED>20130824080000</DTPOSTED>
<TRNAMT>-90</TRNAMT>
<FITID>219381</FITID>
<NAME>China Scuba</NAME>
</STMTTRN>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>2156.56</BALAMT>
<DTASOF>20130831165153</DTASOF>
</LEDGERBAL>
</STMTRS>
</STMTTRNRS>
</BANKMSGSRSV1>
<CREDITCARDMSGSRSV1>
<CCSTMTTRNRS>
<TRNUID>0</TRNUID>
<STATUS>
<CODE>0</CODE>
<SEVERITY>INFO</SEVERITY>
</STATUS>
<CCSTMTRS>
<CURDEF>USD</CURDEF>
<CCACCTFROM>
<ACCTID>123412341234</ACCTID>
</CCACCTFROM>
<BANKTRANLIST>
</BANKTRANLIST>
<LEDGERBAL>
<BALAMT>-562.00</BALAMT>
<DTASOF>20130831165153</DTASOF>
</LEDGERBAL>
</CCSTMTRS>
</CCSTMTTRNRS>
</CREDITCARDMSGSRSV1>
</OFX>

8
account_bank_statement_import_ofx/tests/__init__.py

@ -0,0 +1,8 @@
# -*- encoding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
from . import test_import_bank_statement
checks = [
test_import_bank_statement
]

33
account_bank_statement_import_ofx/tests/test_import_bank_statement.py

@ -0,0 +1,33 @@
# -*- coding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
from openerp.tests.common import TransactionCase
from openerp.modules.module import get_module_resource
class TestOfxFile(TransactionCase):
"""Tests for import bank statement ofx file format (account.bank.statement.import)
"""
def setUp(self):
super(TestOfxFile, self).setUp()
self.statement_import_model = self.registry('account.bank.statement.import')
self.bank_statement_model = self.registry('account.bank.statement')
def test_ofx_file_import(self):
try:
from ofxparse import OfxParser as ofxparser
except ImportError:
#the Python library isn't installed on the server, the OFX import is unavailable and the test cannot be run
return True
cr, uid = self.cr, self.uid
ofx_file_path = get_module_resource('account_bank_statement_import_ofx', 'test_ofx_file', 'test_ofx.ofx')
ofx_file = open(ofx_file_path, 'rb').read().encode('base64')
bank_statement_id = self.statement_import_model.create(cr, uid, dict(
file_type='ofx',
data_file=ofx_file,
))
self.statement_import_model.parse_file(cr, uid, [bank_statement_id])
statement_id = self.bank_statement_model.search(cr, uid, [('name', '=', '000000123')])[0]
bank_st_record = self.bank_statement_model.browse(cr, uid, statement_id)
self.assertEquals(bank_st_record.balance_start, 2156.56)
self.assertEquals(bank_st_record.balance_end_real, 1796.56)

4
account_bank_statement_import_qif/__init__.py

@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
from . import account_bank_statement_import_qif
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

32
account_bank_statement_import_qif/__openerp__.py

@ -0,0 +1,32 @@
# -*- coding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
{
'name': 'Import QIF Bank Statement',
'version': '1.0',
'author': 'OpenERP SA',
'description': '''
Module to 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
Accounting \ Bank and Cash \ Bank Statements.
Bank Statements may be generated containing a subset of the QIF information (only those transaction lines that are required for the
creation of the Financial Accounting records).
Backported from Odoo 9.0
When testing with the provided test file, make sure the demo data from the
base account_bank_statement_import module has been imported, or manually
create periods for the year 2013.
''',
'images' : [],
'depends': ['account_bank_statement_import'],
'demo': [],
'data': [],
'auto_install': False,
'installable': True,
}
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

77
account_bank_statement_import_qif/account_bank_statement_import_qif.py

@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
import dateutil.parser
import base64
from tempfile import TemporaryFile
from openerp.tools.translate import _
from openerp.osv import osv
from openerp.addons.account_bank_statement_import import account_bank_statement_import as ibs
ibs.add_file_type(('qif', 'QIF'))
class account_bank_statement_import(osv.TransientModel):
_inherit = "account.bank.statement.import"
def process_qif(self, cr, uid, data_file, journal_id=False, context=None):
""" Import a file in the .QIF format"""
try:
fileobj = TemporaryFile('wb+')
fileobj.write(base64.b64decode(data_file))
fileobj.seek(0)
file_data = ""
for line in fileobj.readlines():
file_data += line
fileobj.close()
if '\r' in file_data:
data_list = file_data.split('\r')
else:
data_list = file_data.split('\n')
header = data_list[0].strip()
header = header.split(":")[1]
except:
raise osv.except_osv(_('Import Error!'), _('Please check QIF file format is proper or not.'))
line_ids = []
vals_line = {}
total = 0
if header == "Bank":
vals_bank_statement = {}
for line in data_list:
line = line.strip()
if not line:
continue
if line[0] == 'D': # date of transaction
vals_line['date'] = dateutil.parser.parse(line[1:], fuzzy=True).date()
if vals_line.get('date') and not vals_bank_statement.get('period_id'):
period_ids = self.pool.get('account.period').find(cr, uid, vals_line['date'], context=context)
vals_bank_statement.update({'period_id': period_ids and period_ids[0] or False})
elif line[0] == 'T': # Total amount
total += float(line[1:].replace(',', ''))
vals_line['amount'] = float(line[1:].replace(',', ''))
elif line[0] == 'N': # Check number
vals_line['ref'] = line[1:]
elif line[0] == 'P': # Payee
bank_account_id, partner_id = self._detect_partner(cr, uid, line[1:], identifying_field='owner_name', context=context)
vals_line['partner_id'] = partner_id
vals_line['bank_account_id'] = bank_account_id
vals_line['name'] = 'name' in vals_line and line[1:] + ': ' + vals_line['name'] or line[1:]
elif line[0] == 'M': # Memo
vals_line['name'] = 'name' in vals_line and vals_line['name'] + ': ' + line[1:] or line[1:]
elif line[0] == '^': # end of item
line_ids.append((0, 0, vals_line))
vals_line = {}
elif line[0] == '\n':
line_ids = []
else:
pass
else:
raise osv.except_osv(_('Error!'), _('Cannot support this Format !Type:%s.') % (header,))
vals_bank_statement.update({'balance_end_real': total,
'line_ids': line_ids,
'journal_id': journal_id})
return [vals_bank_statement]
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

21
account_bank_statement_import_qif/test_qif_file/test_qif.qif

@ -0,0 +1,21 @@
!Type:Bank
D8/12/13
T-1,000.00
PDelta PC
^
D8/15/13
T-75.46
PWalts Drugs
^
D3/3/13
T-379.00
PEpic Technologies
^
D3/4/13
T-20.28
PYOUR LOCAL SUPERMARKET
^
D3/3/13
T-421.35
PSPRINGFIELD WATER UTILITY
^

8
account_bank_statement_import_qif/tests/__init__.py

@ -0,0 +1,8 @@
# -*- coding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
from . import test_import_bank_statement
checks = [
test_import_bank_statement
]

30
account_bank_statement_import_qif/tests/test_import_bank_statement.py

@ -0,0 +1,30 @@
# -*- coding: utf-8 -*-
# noqa: This is a backport from Odoo. OCA has no control over style here.
# flake8: noqa
from openerp.tests.common import TransactionCase
from openerp.modules.module import get_module_resource
class TestQifFile(TransactionCase):
"""Tests for import bank statement qif file format (account.bank.statement.import)
"""
def setUp(self):
super(TestQifFile, self).setUp()
self.statement_import_model = self.registry('account.bank.statement.import')
self.bank_statement_model = self.registry('account.bank.statement')
self.bank_statement_line_model = self.registry('account.bank.statement.line')
def test_qif_file_import(self):
from openerp.tools import float_compare
cr, uid = self.cr, self.uid
qif_file_path = get_module_resource('account_bank_statement_import_qif', 'test_qif_file', 'test_qif.qif')
qif_file = open(qif_file_path, 'rb').read().encode('base64')
bank_statement_id = self.statement_import_model.create(cr, uid, dict(
file_type='qif',
data_file=qif_file,
))
self.statement_import_model.parse_file(cr, uid, [bank_statement_id])
line_id = self.bank_statement_line_model.search(cr, uid, [('name', '=', 'YOUR LOCAL SUPERMARKET')])[0]
statement_id = self.bank_statement_line_model.browse(cr, uid, line_id).statement_id.id
bank_st_record = self.bank_statement_model.browse(cr, uid, statement_id)
assert float_compare(bank_st_record.balance_end_real, -1896.09, 2) == 0
Loading…
Cancel
Save