Browse Source

fixup! [ADD] Improved module base_bank_account_number_unique.

pull/153/head
Ronald Portier 7 years ago
parent
commit
2207c5bb14
  1. 4
      account_bank_statement_import/models/account_bank_statement_import.py
  2. 2
      account_bank_statement_import/models/account_journal.py
  3. 37
      account_bank_statement_import/models/res_partner_bank.py
  4. 2
      account_bank_statement_import/tests/test_import_file.py
  5. 14
      account_bank_statement_import_camt/models/account_bank_statement_import.py
  6. 12
      account_bank_statement_import_camt/models/parser.py
  7. 32
      account_bank_statement_import_mt940_nl_ing/account_bank_statement_import.py
  8. 31
      account_bank_statement_import_mt940_nl_rabo/account_bank_statement_import.py
  9. 2
      account_bank_statement_import_ofx/account_bank_statement_import_ofx.py
  10. 2
      account_bank_statement_import_qif/account_bank_statement_import_qif.py
  11. 4
      base_bank_account_number_unique/README.rst
  12. 14
      base_bank_account_number_unique/models/res_partner_bank.py
  13. 4
      base_bank_account_number_unique/tests/test_base_bank_account_number_unique.py

4
account_bank_statement_import/models/account_bank_statement_import.py

@ -36,7 +36,7 @@ class AccountBankStatementImport(models.TransientModel):
_description = 'Import Bank Statement' _description = 'Import Bank Statement'
@api.model @api.model
def _get_hide_journal_field(self):
def _compute_hide_journal_field(self):
""" Return False if the journal_id can't be provided by the parsed """ Return False if the journal_id can't be provided by the parsed
file and must be provided by the wizard. file and must be provided by the wizard.
See account_bank_statement_import_qif """ See account_bank_statement_import_qif """
@ -50,7 +50,7 @@ class AccountBankStatementImport(models.TransientModel):
'doesn\'t allow automatic journal detection (QIF for example).') 'doesn\'t allow automatic journal detection (QIF for example).')
hide_journal_field = fields.Boolean( hide_journal_field = fields.Boolean(
string='Hide the journal field in the view', string='Hide the journal field in the view',
compute='_get_hide_journal_field')
compute='_compute_hide_journal_field')
data_file = fields.Binary( data_file = fields.Binary(
'Bank Statement File', required=True, 'Bank Statement File', required=True,
help='Get you bank statements in electronic format from your bank ' help='Get you bank statements in electronic format from your bank '

2
account_bank_statement_import/models/account_journal.py

@ -4,7 +4,7 @@
from openerp import models, fields from openerp import models, fields
class account_journal(models.Model):
class AccountJournal(models.Model):
_inherit = 'account.journal' _inherit = 'account.journal'
enforce_sequence = fields.Boolean( enforce_sequence = fields.Boolean(

37
account_bank_statement_import/models/res_partner_bank.py

@ -1,28 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
##############################################################################
#
# This file is part of account_bank_statement_import,
# an Odoo module.
#
# Copyright (c) 2015 ACSONE SA/NV (<http://acsone.eu>)
#
# account_bank_statement_importis free software:
# you can redistribute it and/or modify it under the terms of the GNU
# Affero General Public License as published by the Free Software
# Foundation,either version 3 of the License, or (at your option) any
# later version.
#
# account_bank_statement_import is distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with account_bank_statement_import_coda.
# If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# Copyright 2015 ACSONE SA/NV <http://acsone.eu>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import re import re
from openerp import api, models, fields from openerp import api, models, fields
@ -32,7 +10,7 @@ class ResPartnerBank(models.Model):
sanitized_acc_number = fields.Char( sanitized_acc_number = fields.Char(
'Sanitized Account Number', size=64, readonly=True, 'Sanitized Account Number', size=64, readonly=True,
compute='_get_sanitized_account_number', store=True, index=True)
compute='_compute_sanitized_acc_number', store=True, index=True)
enforce_unique_import_lines = fields.Boolean( enforce_unique_import_lines = fields.Boolean(
string='Force unique lines on import', string='Force unique lines on import',
help="Some banks do not provide an unique id for transactions in" help="Some banks do not provide an unique id for transactions in"
@ -51,11 +29,12 @@ class ResPartnerBank(models.Model):
return re.sub(r'\W+', '', acc_number).upper() return re.sub(r'\W+', '', acc_number).upper()
return False return False
@api.one
@api.multi
@api.depends('acc_number') @api.depends('acc_number')
def _get_sanitized_account_number(self):
self.sanitized_acc_number = self._sanitize_account_number(
self.acc_number)
def _compute_sanitized_acc_number(self):
for this in self:
this.sanitized_acc_number = this._sanitize_account_number(
this.acc_number)
@api.model @api.model
def search(self, args, offset=0, limit=None, order=None, count=False): def search(self, args, offset=0, limit=None, order=None, count=False):

2
account_bank_statement_import/tests/test_import_file.py

@ -81,7 +81,7 @@ class TestStatementFile(TransactionCase):
self.env.cr.execute( self.env.cr.execute(
"select name, date, amount, ref, bank_account_id" "select name, date, amount, ref, bank_account_id"
" from account_bank_statement_line" " from account_bank_statement_line"
" where statement_id=%d" % statement_obj.id)
" where statement_id=%s", (statement_obj.id, ))
_logger.error( _logger.error(
"Transaction not found in %s" % "Transaction not found in %s" %
str(self.cr.fetchall()) str(self.cr.fetchall())

14
account_bank_statement_import_camt/models/account_bank_statement_import.py

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2013-2017 Therp BV <http://therp.nl>.
# Copyright 2013-2018 Therp BV <http://therp.nl>.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging import logging
from openerp import models
from openerp import api, models
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
@ -12,9 +13,10 @@ class AccountBankStatementImport(models.TransientModel):
"""Add process_camt method to account.bank.statement.import.""" """Add process_camt method to account.bank.statement.import."""
_inherit = 'account.bank.statement.import' _inherit = 'account.bank.statement.import'
def _parse_file(self, cr, uid, data_file, context=None):
@api.model
def _parse_file(self, data_file):
"""Parse a CAMT053 XML file.""" """Parse a CAMT053 XML file."""
parser = self.pool['account.bank.statement.import.camt.parser']
parser = self.env['account.bank.statement.import.camt.parser']
try: try:
_logger.debug("Try parsing with camt.") _logger.debug("Try parsing with camt.")
return parser.parse(data_file) return parser.parse(data_file)
@ -23,5 +25,5 @@ class AccountBankStatementImport(models.TransientModel):
_logger.debug( _logger.debug(
"Statement file was not a camt file.", exc_info=True "Statement file was not a camt file.", exc_info=True
) )
return super(AccountBankStatementImport, self)._parse_file(
cr, uid, data_file, context=context)
return super(
AccountBankStatementImport, self)._parse_file(data_file)

12
account_bank_statement_import_camt/models/parser.py

@ -5,7 +5,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging import logging
import re import re
from copy import copy
from datetime import datetime from datetime import datetime
from lxml import etree from lxml import etree
@ -22,11 +21,6 @@ class CamtParser(models.AbstractModel):
"""Parser for camt bank statement import files.""" """Parser for camt bank statement import files."""
_name = 'account.bank.statement.import.camt.parser' _name = 'account.bank.statement.import.camt.parser'
def __init__(self):
"""Define and initialize attributes."""
super(CamtParser, self).__init__()
self.namespace = ''
def xpath(self, node, expr): def xpath(self, node, expr):
""" """
Wrap namespaces argument into call to Element.xpath(): Wrap namespaces argument into call to Element.xpath():
@ -78,7 +72,7 @@ class CamtParser(models.AbstractModel):
if default: if default:
setattr(obj, attr_name, default) setattr(obj, attr_name, default)
def parse_transaction_details(self, ns, node, transaction):
def parse_transaction_details(self, node, transaction):
"""Parse TxDtls node.""" """Parse TxDtls node."""
# message # message
self.add_value_from_node( self.add_value_from_node(
@ -102,7 +96,7 @@ class CamtParser(models.AbstractModel):
], ],
transaction, 'eref' transaction, 'eref'
) )
amount = self.parse_amount(ns, node)
amount = self.parse_amount(node)
if amount != 0.0: if amount != 0.0:
transaction['amount'] = amount transaction['amount'] = amount
# remote party values # remote party values
@ -168,7 +162,7 @@ class CamtParser(models.AbstractModel):
self.add_value_from_node( self.add_value_from_node(
node, node,
['./ns:NtryDtls/ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref', ['./ns:NtryDtls/ns:RmtInf/ns:Strd/ns:CdtrRefInf/ns:Ref',
'./ns:NtryDtls/ns:Btch/ns:PmtInfId'],
'./ns:NtryDtls/ns:Btch/ns:PmtInfId'],
transaction, transaction,
'eref') 'eref')
details_nodes = node.xpath( details_nodes = node.xpath(

32
account_bank_statement_import_mt940_nl_ing/account_bank_statement_import.py

@ -1,25 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Parse a MT940 ING file."""
##############################################################################
#
# Copyright (C) 2013-2015 Therp BV <http://therp.nl>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# Copyright 2013-2018 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging import logging
from openerp import models
from openerp import api, models
from .mt940 import MT940Parser as Parser from .mt940 import MT940Parser as Parser
@ -30,7 +15,8 @@ class AccountBankStatementImport(models.TransientModel):
"""Add parsing of mt940 files to bank statement import.""" """Add parsing of mt940 files to bank statement import."""
_inherit = 'account.bank.statement.import' _inherit = 'account.bank.statement.import'
def _parse_file(self, cr, uid, data_file, context=None):
@api.model
def _parse_file(self, data_file):
"""Parse a MT940 IBAN ING file.""" """Parse a MT940 IBAN ING file."""
parser = Parser() parser = Parser()
try: try:
@ -40,5 +26,5 @@ class AccountBankStatementImport(models.TransientModel):
# Returning super will call next candidate: # Returning super will call next candidate:
_logger.debug("Statement file was not a MT940 IBAN ING file.", _logger.debug("Statement file was not a MT940 IBAN ING file.",
exc_info=True) exc_info=True)
return super(AccountBankStatementImport, self)._parse_file(
cr, uid, data_file, context=context)
return super(
AccountBankStatementImport, self)._parse_file(data_file)

31
account_bank_statement_import_mt940_nl_rabo/account_bank_statement_import.py

@ -1,26 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
"""Parse a MT940 RABO file."""
##############################################################################
#
# Copyright (C) 2013-2015 Therp BV <http://therp.nl>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
# Copyright 2013-2018 Therp BV <http://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import logging import logging
from openerp import models
from openerp import api, models
from .mt940 import MT940Parser as Parser from .mt940 import MT940Parser as Parser
@ -31,7 +15,8 @@ class AccountBankStatementImport(models.TransientModel):
"""Add parsing of RABO mt940 files to bank statement import.""" """Add parsing of RABO mt940 files to bank statement import."""
_inherit = 'account.bank.statement.import' _inherit = 'account.bank.statement.import'
def _parse_file(self, cr, uid, data_file, context=None):
@api.model
def _parse_file(self, data_file):
"""Parse a MT940 RABO file.""" """Parse a MT940 RABO file."""
parser = Parser() parser = Parser()
try: try:
@ -42,5 +27,5 @@ class AccountBankStatementImport(models.TransientModel):
# Returning super will call next candidate: # Returning super will call next candidate:
_logger.debug("Statement file was not a MT940 RABO file.", _logger.debug("Statement file was not a MT940 RABO file.",
exc_info=True) exc_info=True)
return super(AccountBankStatementImport, self)._parse_file(
cr, uid, data_file, context=context)
return super(
AccountBankStatementImport, self)._parse_file(data_file)

2
account_bank_statement_import_ofx/account_bank_statement_import_ofx.py

@ -25,7 +25,7 @@ class AccountBankStatementImport(models.TransientModel):
return False return False
try: try:
ofx = ofxparser.parse(StringIO.StringIO(data_file)) ofx = ofxparser.parse(StringIO.StringIO(data_file))
except:
except Exception:
return False return False
return ofx return ofx

2
account_bank_statement_import_qif/account_bank_statement_import_qif.py

@ -35,7 +35,7 @@ class AccountBankStatementImport(models.TransientModel):
data_list = file_data.split('\n') data_list = file_data.split('\n')
header = data_list[0].strip() header = data_list[0].strip()
header = header.split(":")[1] header = header.split(":")[1]
except:
except Exception:
raise UserError(_('Could not decipher the QIF file.')) raise UserError(_('Could not decipher the QIF file.'))
transactions = [] transactions = []
vals_line = {} vals_line = {}

4
base_bank_account_number_unique/README.rst

@ -18,7 +18,9 @@ a SQL unique index. This has the added advantage, that the module can be
installed on databases where the bank-account numbers are not unique already. installed on databases where the bank-account numbers are not unique already.
To find records that are not unique, you could use the following SQL To find records that are not unique, you could use the following SQL
statement.
statement:
.. code-block:: sql
with res_partner_bank_sanitized as ( with res_partner_bank_sanitized as (
select select

14
base_bank_account_number_unique/models/res_partner_bank.py

@ -1,5 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# © 2015-2017 Therp BV <https://therp.nl>
# Copyright 2015-2018 Therp BV <https://therp.nl>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from openerp import api, models, _ from openerp import api, models, _
from openerp.exceptions import ValidationError from openerp.exceptions import ValidationError
@ -8,13 +8,13 @@ from openerp.exceptions import ValidationError
class ResPartnerBank(models.Model): class ResPartnerBank(models.Model):
_inherit = 'res.partner.bank' _inherit = 'res.partner.bank'
def copy_data(self, cr, uid, id, default=None, context=None):
@api.multi
def copy_data(self, default=None):
default = default or {} default = default or {}
context = context or {}
if 'acc_number' not in default and 'default_acc_number' not in context:
if 'acc_number' not in default and \
'default_acc_number' not in self.env.context:
default['acc_number'] = '' default['acc_number'] = ''
return super(ResPartnerBank, self).copy_data(
cr, uid, id, default=default, context=context)
return super(ResPartnerBank, self).copy_data(default=default)
@api.constrains('company_id', 'sanitized_acc_number') @api.constrains('company_id', 'sanitized_acc_number')
def _check_unique_account(self): def _check_unique_account(self):
@ -35,6 +35,6 @@ class ResPartnerBank(models.Model):
raise ValidationError( raise ValidationError(
_("Bank account %s already registered for %s.") % _("Bank account %s already registered for %s.") %
(this.acc_number, (this.acc_number,
already_existing.partner_id.display_name or
already_existing.partner_id.display_name or
_("unknown partner")) _("unknown partner"))
) )

4
base_bank_account_number_unique/tests/test_base_bank_account_number_unique.py

@ -15,10 +15,6 @@ class TestBaseBankAccountNumberUnique(TransactionCase):
'acc_number': 'BE1234567890', 'acc_number': 'BE1234567890',
'state': 'bank', 'state': 'bank',
}) })
bank_account_model.create({
'acc_number': 'BE 1234 567 890',
'state': 'bank',
})
with self.assertRaises(ValidationError): with self.assertRaises(ValidationError):
bank_account_model.create({ bank_account_model.create({
'acc_number': 'BE 1234 567 890', 'acc_number': 'BE 1234 567 890',

Loading…
Cancel
Save