From 3adb27ef0e71bc79429534698162a9490aeb7f10 Mon Sep 17 00:00:00 2001 From: Matthieu Dietrich Date: Tue, 26 Apr 2016 16:17:11 +0200 Subject: [PATCH 01/32] First commit to migrate and merge base_import, base_completion and commission --- account_statement_base_completion/data.xml | 31 - .../partner_view.xml | 21 - .../statement.py | 654 ------------------ account_statement_base_import/__init__.py | 2 +- account_statement_base_import/__openerp__.py | 10 +- .../data/completion_rule_data.xml | 22 + .../models/__init__.py | 24 + .../models/account_journal.py | 281 ++++++++ .../models/account_move.py | 392 +++++++++++ .../models}/partner.py | 21 +- .../parser/__init__.py | 4 +- .../parser/file_parser.py | 31 +- .../parser/generic_file_parser.py | 10 +- .../parser/parser.py | 52 +- account_statement_base_import/statement.py | 255 ------- .../statement_view.xml | 45 -- .../tests/__init__.py | 2 + .../tests/test_base_completion.py | 0 .../views/account_move_view.xml | 20 + .../views/journal_view.xml | 32 + .../views/partner_view.xml | 15 + .../wizard/import_statement.py | 122 ++-- .../wizard/import_statement_view.xml | 71 +- 23 files changed, 924 insertions(+), 1193 deletions(-) delete mode 100644 account_statement_base_completion/data.xml delete mode 100644 account_statement_base_completion/partner_view.xml delete mode 100644 account_statement_base_completion/statement.py create mode 100644 account_statement_base_import/data/completion_rule_data.xml create mode 100644 account_statement_base_import/models/__init__.py create mode 100644 account_statement_base_import/models/account_journal.py create mode 100644 account_statement_base_import/models/account_move.py rename {account_statement_base_completion => account_statement_base_import/models}/partner.py (68%) delete mode 100644 account_statement_base_import/statement.py delete mode 100644 account_statement_base_import/statement_view.xml rename {account_statement_base_completion => account_statement_base_import}/tests/test_base_completion.py (100%) create mode 100644 account_statement_base_import/views/account_move_view.xml create mode 100644 account_statement_base_import/views/journal_view.xml create mode 100644 account_statement_base_import/views/partner_view.xml diff --git a/account_statement_base_completion/data.xml b/account_statement_base_completion/data.xml deleted file mode 100644 index 595a4af3..00000000 --- a/account_statement_base_completion/data.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - Match from line label (based on partner field 'Bank Statement Label') - 60 - get_from_label_and_partner_field - - - - Match from line label (based on partner name) - 70 - get_from_label_and_partner_name - - - - Match from line reference (based on Invoice number) - 40 - get_from_ref_and_invoice - - - - Match from line reference (based on Invoice Supplier number) - 45 - get_from_ref_and_supplier_invoice - - - - - diff --git a/account_statement_base_completion/partner_view.xml b/account_statement_base_completion/partner_view.xml deleted file mode 100644 index 94be85c3..00000000 --- a/account_statement_base_completion/partner_view.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - account_bank_statement_import.view.partner.form - res.partner - 20 - - - - - - - - - - - diff --git a/account_statement_base_completion/statement.py b/account_statement_base_completion/statement.py deleted file mode 100644 index 12bf2d31..00000000 --- a/account_statement_base_completion/statement.py +++ /dev/null @@ -1,654 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Nicolas Bessi, Joel Grand-Guillaume -# Copyright 2011-2012 Camptocamp SA -# -# 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 . -# -############################################################################## -# TODO replace customer supplier by package constant -import traceback -import sys -import logging -import simplejson -import inspect -import datetime - -import psycopg2 - -from collections import defaultdict -import re -from openerp.tools.translate import _ -from openerp.osv import orm, fields -from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT -from operator import attrgetter - - -_logger = logging.getLogger(__name__) - - -class ErrorTooManyPartner(Exception): - """ New Exception definition that is raised when more than one partner is - matched by the completion rule. - """ - - def __init__(self, value): - self.value = value - - def __str__(self): - return repr(self.value) - - def __repr__(self): - return repr(self.value) - - -class AccountStatementProfil(orm.Model): - """Extend the class to add rules per profile that will match at least the - partner, but it could also be used to match other values as well. - """ - _inherit = "account.statement.profile" - - _columns = { - # @Akretion: For now, we don't implement this features, but this would - # probably be there: 'auto_completion': fields.text('Auto Completion'), - # 'transferts_account_id':fields.many2one('account.account', - # 'Transferts Account'), - # => You can implement it in a module easily, we design it with your - # needs in mind as well! - - 'rule_ids': fields.many2many( - 'account.statement.completion.rule', - string='Related statement profiles', - rel='as_rul_st_prof_rel'), - } - - def _get_rules(self, cr, uid, profile, context=None): - if isinstance(profile, (int, long)): - prof = self.browse(cr, uid, profile, context=context) - else: - prof = profile - # We need to respect the sequence order - return sorted(prof.rule_ids, key=attrgetter('sequence')) - - def _find_values_from_rules(self, cr, uid, calls, line, context=None): - """This method will execute all related rules, in their sequence order, - to retrieve all the values returned by the first rules that will match. - :param calls: list of lookup function name available in rules - :param dict line: read of the concerned account.bank.statement.line - :return: - A dict of value that can be passed directly to the write method of - the statement line or {} - {'partner_id': value, - 'account_id: value, - - ...} - """ - if not calls: - calls = self._get_rules( - cr, uid, line['profile_id'], context=context) - rule_obj = self.pool.get('account.statement.completion.rule') - for call in calls: - method_to_call = getattr(rule_obj, call.function_to_call) - if len(inspect.getargspec(method_to_call).args) == 6: - result = method_to_call(cr, uid, call.id, line, context) - else: - result = method_to_call(cr, uid, line, context) - if result: - result['already_completed'] = True - return result - return None - - -class AccountStatementCompletionRule(orm.Model): - """This will represent all the completion method that we can have to - fullfill the bank statement lines. You'll be able to extend them in you own - module and choose those to apply for every statement profile. - The goal of a rule is to fullfill at least the partner of the line, but - if possible also the reference because we'll use it in the reconciliation - process. The reference should contain the invoice number or the SO number - or any reference that will be matched by the invoice accounting move. - """ - _name = "account.statement.completion.rule" - _order = "sequence asc" - - def _get_functions(self, cr, uid, context=None): - """List of available methods for rules. - - Override this to add you own.""" - return [ - ('get_from_ref_and_invoice', - 'From line reference (based on customer invoice number)'), - ('get_from_ref_and_supplier_invoice', - 'From line reference (based on supplier invoice number)'), - ('get_from_label_and_partner_field', - 'From line label (based on partner field)'), - ('get_from_label_and_partner_name', - 'From line label (based on partner name)') - ] - - def __get_functions(self, cr, uid, context=None): - """ Call method which can be inherited """ - return self._get_functions(cr, uid, context=context) - - _columns = { - 'sequence': fields.integer('Sequence', - help="Lower means parsed first."), - 'name': fields.char('Name', size=128), - 'profile_ids': fields.many2many( - 'account.statement.profile', - rel='as_rul_st_prof_rel', - string='Related statement profiles'), - 'function_to_call': fields.selection(__get_functions, 'Method'), - } - - def _find_invoice(self, cr, uid, st_line, inv_type, context=None): - """Find invoice related to statement line""" - inv_obj = self.pool.get('account.invoice') - if inv_type == 'supplier': - type_domain = ('in_invoice', 'in_refund') - number_field = 'supplier_invoice_number' - elif inv_type == 'customer': - type_domain = ('out_invoice', 'out_refund') - number_field = 'number' - else: - raise orm.except_orm( - _('System error'), - _('Invalid invoice type for completion: %') % inv_type) - - inv_id = inv_obj.search(cr, uid, - [(number_field, '=', st_line['ref'].strip()), - ('type', 'in', type_domain)], - context=context) - if inv_id: - if len(inv_id) == 1: - inv = inv_obj.browse(cr, uid, inv_id[0], context=context) - else: - raise ErrorTooManyPartner( - _('Line named "%s" (Ref:%s) was matched by more than one ' - 'partner while looking on %s invoices') % - (st_line['name'], st_line['ref'], inv_type)) - return inv - return False - - def _from_invoice(self, cr, uid, line, inv_type, context): - """Populate statement line values""" - if inv_type not in ('supplier', 'customer'): - raise orm.except_orm(_('System error'), - _('Invalid invoice type for completion: %') % - inv_type) - res = {} - inv = self._find_invoice(cr, uid, line, inv_type, context=context) - if inv: - partner_id = inv.commercial_partner_id.id - res = {'partner_id': partner_id, - 'account_id': inv.account_id.id, - 'type': inv_type} - override_acc = line['master_account_id'] - if override_acc: - res['account_id'] = override_acc - return res - - # Should be private but data are initialised with no update XML - def get_from_ref_and_supplier_invoice(self, cr, uid, line, context=None): - """Match the partner based on the invoice supplier invoice number and - the reference of the statement line. Then, call the generic - get_values_for_line method to complete other values. If more than one - partner matched, raise the ErrorTooManyPartner error. - - :param dict line: read of the concerned account.bank.statement.line - :return: - A dict of value that can be passed directly to the write method of - the statement line or {} - {'partner_id': value, - 'account_id': value, - - ...} - """ - return self._from_invoice(cr, uid, line, 'supplier', context=context) - - # Should be private but data are initialised with no update XML - def get_from_ref_and_invoice(self, cr, uid, line, context=None): - """Match the partner based on the invoice number and the reference of - the statement line. Then, call the generic get_values_for_line method - to complete other values. If more than one partner matched, raise the - ErrorTooManyPartner error. - - :param dict line: read of the concerned account.bank.statement.line - :return: - A dict of value that can be passed directly to the write method of - the statement line or {} - {'partner_id': value, - 'account_id': value, - ...} - """ - return self._from_invoice(cr, uid, line, 'customer', context=context) - - # Should be private but data are initialised with no update XML - def get_from_label_and_partner_field(self, cr, uid, st_line, context=None): - """ - Match the partner based on the label field of the statement line and - the text defined in the 'bank_statement_label' field of the partner. - Remember that we can have values separated with ; Then, call the - generic get_values_for_line method to complete other values. If more - than one partner matched, raise the ErrorTooManyPartner error. - - :param dict st_line: read of the concerned account.bank.statement.line - :return: - A dict of value that can be passed directly to the write method of - the statement line or {} - {'partner_id': value, - 'account_id': value, - - ...} - """ - partner_obj = self.pool['res.partner'] - st_obj = self.pool.get('account.bank.statement.line') - res = {} - # As we have to iterate on each partner for each line, - #  we memoize the pair to avoid - # to redo computation for each line. - # Following code can be done by a single SQL query - # but this option is not really maintanable - if not context.get('label_memoizer'): - context['label_memoizer'] = defaultdict(list) - partner_ids = partner_obj.search( - cr, uid, [('bank_statement_label', '!=', False)], - context=context) - line_ids = context.get('line_ids', []) - for partner in partner_obj.browse(cr, uid, partner_ids, - context=context): - vals = '|'.join( - re.escape(x.strip()) - for x in partner.bank_statement_label.split(';')) - or_regex = ".*%s.*" % vals - sql = ("SELECT id from account_bank_statement_line" - " WHERE id in %s" - " AND name ~* %s") - cr.execute(sql, (line_ids, or_regex)) - pairs = cr.fetchall() - for pair in pairs: - context['label_memoizer'][pair[0]].append(partner) - if st_line['id'] in context['label_memoizer']: - found_partner = context['label_memoizer'][st_line['id']] - if len(found_partner) > 1: - msg = (_('Line named "%s" (Ref:%s) was matched by more than ' - 'one partner while looking on partner label: %s') % - (st_line['name'], st_line['ref'], - ','.join([x.name for x in found_partner]))) - raise ErrorTooManyPartner(msg) - res['partner_id'] = found_partner[0].id - st_vals = st_obj.get_values_for_line( - cr, uid, profile_id=st_line['profile_id'], - master_account_id=st_line['master_account_id'], - partner_id=found_partner[0].id, line_type=False, - amount=st_line['amount'] if st_line['amount'] else 0.0, - context=context) - res.update(st_vals) - return res - - def get_from_label_and_partner_name(self, cr, uid, st_line, context=None): - """Match the partner based on the label field of the statement line and - the name of the partner. Then, call the generic get_values_for_line - method to complete other values. If more than one partner matched, - raise the ErrorTooManyPartner error. - - :param dict st_line: read of the concerned account.bank.statement.line - :return: - A dict of value that can be passed directly to the write method of - the statement line or {} - {'partner_id': value, - 'account_id': value, - - ...} - """ - res = {} - # We memoize allowed partner - if not context.get('partner_memoizer'): - context['partner_memoizer'] = tuple( - self.pool['res.partner'].search(cr, uid, [])) - if not context['partner_memoizer']: - return res - st_obj = self.pool.get('account.bank.statement.line') - # The regexp_replace() escapes the name to avoid false positive - # example: 'John J. Doe (No 1)' is escaped to 'John J\. Doe \(No 1\)' - # See http://stackoverflow.com/a/400316/1504003 for a list of - # chars to escape. Postgres is POSIX-ARE, compatible with - # POSIX-ERE excepted that '\' must be escaped inside brackets according - # to: - # http://www.postgresql.org/docs/9.0/static/functions-matching.html - # in chapter 9.7.3.6. Limits and Compatibility - sql = r""" - SELECT id FROM ( - SELECT id, - regexp_matches(%s, - regexp_replace(name,'([\.\^\$\*\+\?\(\)\[\{\\\|])', %s, - 'g'), 'i') AS name_match - FROM res_partner - WHERE id IN %s) - AS res_patner_matcher - WHERE name_match IS NOT NULL""" - cr.execute( - sql, (st_line['name'], r"\\\1", context['partner_memoizer'])) - result = cr.fetchall() - if not result: - return res - if len(result) > 1: - raise ErrorTooManyPartner( - _('Line named "%s" (Ref:%s) was matched by more than one ' - 'partner while looking on partner by name') % - (st_line['name'], st_line['ref'])) - res['partner_id'] = result[0][0] - st_vals = st_obj.get_values_for_line( - cr, uid, profile_id=st_line['profile_id'], - master_account_id=st_line['master_account_id'], - partner_id=res['partner_id'], line_type=False, - amount=st_line['amount'] if st_line['amount'] else 0.0, - context=context) - res.update(st_vals) - return res - - -class AccountStatement(orm.Model): - _inherit = "account.bank.statement" - - def button_confirm_bank(self, cr, uid, ids, context=None): - line_obj = self.pool['account.bank.statement.line'] - for stat_id in ids: - line_without_account = line_obj.search(cr, uid, [ - ['statement_id', '=', stat_id], - ['account_id', '=', False], - ], context=context) - if line_without_account: - stat = self.browse(cr, uid, stat_id, context=context) - raise orm.except_orm( - _('User error'), - _('You should fill all account on the line of the' - ' statement %s') % stat.name) - return super(AccountStatement, self).button_confirm_bank( - cr, uid, ids, context=context) - - -class AccountStatementLine(orm.Model): - """ - Add sparse field on the statement line to allow to store all the bank infos - that are given by a bank/office. You can then add you own in your module. - The idea here is to store all bank/office infos in the - additionnal_bank_fields serialized field when importing the file. If many - values, add a tab in the bank statement line to store your specific one. - Have a look in account_statement_base_import module to see how we've done - it. - """ - _inherit = "account.bank.statement.line" - _order = "already_completed desc, date asc" - - _columns = { - 'additionnal_bank_fields': fields.serialized( - 'Additionnal infos from bank', - help="Used by completion and import system. Adds every field that " - "is present in your bank/office statement file"), - 'label': fields.sparse( - type='char', - string='Label', - serialization_field='additionnal_bank_fields', - help="Generic field to store a label given from the " - "bank/office on which we can base the default/standard " - "providen rule."), - 'already_completed': fields.boolean( - "Auto-Completed", - help="When this checkbox is ticked, the auto-completion " - "process/button will ignore this line."), - # Set account_id field as optional by removing required option. - 'account_id': fields.many2one('account.account', 'Account'), - } - - _defaults = { - 'already_completed': False, - } - - def _get_line_values_from_rules(self, cr, uid, line, rules, context=None): - """We'll try to find out the values related to the line based on rules - setted on the profile.. We will ignore line for which already_completed - is ticked. - - :return: - A dict of dict value that can be passed directly to the write - method of the statement line or {}. The first dict has statement - line ID as a key: {117009: {'partner_id': 100997, - 'account_id': 489L}} - """ - profile_obj = self.pool['account.statement.profile'] - if line.get('already_completed'): - return {} - # Ask the rule - vals = profile_obj._find_values_from_rules( - cr, uid, rules, line, context) - if vals: - vals['id'] = line['id'] - return vals - return {} - - def _get_available_columns(self, statement_store, - include_serializable=False): - """Return writeable by SQL columns""" - statement_line_obj = self.pool['account.bank.statement.line'] - model_cols = statement_line_obj._columns - avail = [ - k for k, col in model_cols.iteritems() if not hasattr(col, '_fnct') - ] - keys = [k for k in statement_store[0].keys() if k in avail] - # add sparse fields.. - if include_serializable: - for k, col in model_cols.iteritems(): - if k in statement_store[0].keys() and \ - isinstance(col, fields.sparse) and \ - col.serialization_field not in keys and \ - col._type == 'char': - keys.append(col.serialization_field) - keys.sort() - return keys - - def _prepare_insert(self, statement, cols): - """ Apply column formating to prepare data for SQL inserting - Return a copy of statement - """ - st_copy = statement - for k, col in st_copy.iteritems(): - if k in cols: - st_copy[k] = self._columns[k]._symbol_set[1](col) - return st_copy - - def _prepare_manyinsert(self, statement_store, cols): - """ Apply column formating to prepare multiple SQL inserts - Return a copy of statement_store - """ - values = [] - for statement in statement_store: - values.append(self._prepare_insert(statement, cols)) - return values - - def _serialize_sparse_fields(self, cols, statement_store): - """ Serialize sparse fields values in the target serialized field - Return a copy of statement_store - """ - statement_line_obj = self.pool['account.bank.statement.line'] - model_cols = statement_line_obj._columns - sparse_fields = dict( - [(k, col) for k, col in model_cols.iteritems() if isinstance( - col, fields.sparse) and col._type == 'char']) - values = [] - for statement in statement_store: - to_json_k = set() - st_copy = statement.copy() - for k, col in sparse_fields.iteritems(): - if k in st_copy: - to_json_k.add(col.serialization_field) - serialized = st_copy.setdefault( - col.serialization_field, {}) - serialized[k] = st_copy[k] - for k in to_json_k: - st_copy[k] = simplejson.dumps(st_copy[k]) - values.append(st_copy) - return values - - def _insert_lines(self, cr, uid, statement_store, context=None): - """ Do raw insert into database because ORM is awfully slow - when doing batch write. It is a shame that batch function - does not exist""" - statement_line_obj = self.pool['account.bank.statement.line'] - statement_line_obj.check_access_rule(cr, uid, [], 'create') - statement_line_obj.check_access_rights( - cr, uid, 'create', raise_exception=True) - cols = self._get_available_columns( - statement_store, include_serializable=True) - statement_store = self._prepare_manyinsert(statement_store, cols) - tmp_vals = (', '.join(cols), ', '.join(['%%(%s)s' % i for i in cols])) - sql = "INSERT INTO account_bank_statement_line (%s) " \ - "VALUES (%s);" % tmp_vals - try: - cr.executemany( - sql, tuple(self._serialize_sparse_fields(cols, - statement_store))) - except psycopg2.Error as sql_err: - cr.rollback() - raise orm.except_orm(_("ORM bypass error"), - sql_err.pgerror) - - def _update_line(self, cr, uid, vals, context=None): - """ Do raw update into database because ORM is awfully slow - when cheking security. - TODO / WARM: sparse fields are skipped by the method. IOW, if your - completion rule update an sparse field, the updated value will never - be stored in the database. It would be safer to call the update method - from the ORM for records updating this kind of fields. - """ - cols = self._get_available_columns([vals]) - vals = self._prepare_insert(vals, cols) - tmp_vals = (', '.join(['%s = %%(%s)s' % (i, i) for i in cols])) - sql = "UPDATE account_bank_statement_line " \ - "SET %s where id = %%(id)s;" % tmp_vals - try: - cr.execute(sql, vals) - except psycopg2.Error as sql_err: - cr.rollback() - raise orm.except_orm(_("ORM bypass error"), - sql_err.pgerror) - - -class AccountBankStatement(orm.Model): - """We add a basic button and stuff to support the auto-completion - of the bank statement once line have been imported or manually fullfill. - """ - _inherit = "account.bank.statement" - - _columns = { - 'completion_logs': fields.text('Completion Log', readonly=True), - } - - def write_completion_log(self, cr, uid, stat_id, error_msg, - number_imported, context=None): - """Write the log in the completion_logs field of the bank statement to - let the user know what have been done. This is an append mode, so we - don't overwrite what already recoded. - - :param int/long stat_id: ID of the account.bank.statement - :param char error_msg: Message to add - :number_imported int/long: Number of lines that have been completed - :return True - """ - user_name = self.pool.get('res.users').read( - cr, uid, uid, ['name'], context=context)['name'] - statement = self.browse(cr, uid, stat_id, context=context) - number_line = len(statement.line_ids) - log = self.read(cr, uid, stat_id, ['completion_logs'], - context=context)['completion_logs'] - log = log if log else "" - completion_date = datetime.datetime.now().strftime( - DEFAULT_SERVER_DATETIME_FORMAT) - message = (_("%s Bank Statement ID %s has %s/%s lines completed by " - "%s \n%s\n%s\n") % (completion_date, stat_id, - number_imported, number_line, - user_name, error_msg, log)) - self.write( - cr, uid, [stat_id], {'completion_logs': message}, context=context) - - body = (_('Statement ID %s auto-completed for %s/%s lines completed') % - (stat_id, number_imported, number_line)), - self.message_post(cr, uid, [stat_id], body=body, context=context) - return True - - def button_auto_completion(self, cr, uid, ids, context=None): - """Complete line with values given by rules and tic the - already_completed checkbox so we won't compute them again unless the - user untick them! - """ - if context is None: - context = {} - stat_line_obj = self.pool['account.bank.statement.line'] - profile_obj = self.pool.get('account.statement.profile') - compl_lines = 0 - stat_line_obj.check_access_rule(cr, uid, [], 'create') - stat_line_obj.check_access_rights( - cr, uid, 'create', raise_exception=True) - for stat in self.browse(cr, uid, ids, context=context): - msg_lines = [] - ctx = context.copy() - ctx['line_ids'] = tuple((x.id for x in stat.line_ids)) - b_profile = stat.profile_id - rules = profile_obj._get_rules(cr, uid, b_profile, context=context) - # Only for perfo even it gains almost nothing - profile_id = b_profile.id - master_account_id = b_profile.receivable_account_id - master_account_id = master_account_id.id if \ - master_account_id else False - res = False - for line in stat_line_obj.read(cr, uid, ctx['line_ids']): - try: - # performance trick - line['master_account_id'] = master_account_id - line['profile_id'] = profile_id - res = stat_line_obj._get_line_values_from_rules( - cr, uid, line, rules, context=ctx) - if res: - compl_lines += 1 - except ErrorTooManyPartner, exc: - msg_lines.append(repr(exc)) - except Exception, exc: - msg_lines.append(repr(exc)) - error_type, error_value, trbk = sys.exc_info() - st = "Error: %s\nDescription: %s\nTraceback:" % ( - error_type.__name__, error_value) - st += ''.join(traceback.format_tb(trbk, 30)) - _logger.error(st) - if res: - # stat_line_obj.write(cr, uid, [line.id], vals, - # context=ctx) - try: - stat_line_obj._update_line( - cr, uid, res, context=context) - except Exception as exc: - msg_lines.append(repr(exc)) - error_type, error_value, trbk = sys.exc_info() - st = "Error: %s\nDescription: %s\nTraceback:" % ( - error_type.__name__, error_value) - st += ''.join(traceback.format_tb(trbk, 30)) - _logger.error(st) - # we can commit as it is not needed to be atomic - # commiting here adds a nice perfo boost - if not compl_lines % 500: - cr.commit() - msg = u'\n'.join(msg_lines) - self.write_completion_log(cr, uid, stat.id, - msg, compl_lines, context=context) - return True diff --git a/account_statement_base_import/__init__.py b/account_statement_base_import/__init__.py index 2fe60a3e..aadbee9c 100644 --- a/account_statement_base_import/__init__.py +++ b/account_statement_base_import/__init__.py @@ -20,4 +20,4 @@ ############################################################################## from . import parser from . import wizard -from . import statement +from . import models diff --git a/account_statement_base_import/__openerp__.py b/account_statement_base_import/__openerp__.py index 3a920daf..5a576242 100644 --- a/account_statement_base_import/__openerp__.py +++ b/account_statement_base_import/__openerp__.py @@ -26,8 +26,7 @@ 'category': 'Finance', 'complexity': 'normal', 'depends': [ - 'account_statement_ext', - 'account_statement_base_completion' + 'account' ], 'description': """ This module brings basic methods and fields on bank statement to deal with @@ -62,11 +61,14 @@ """, 'website': 'http://www.camptocamp.com', 'data': [ + "data/completion_rule_data.xml", "wizard/import_statement_view.xml", - "statement_view.xml", + "views/account_move_view.xml", + "views/journal_view.xml", + "views/partner_view.xml", ], 'test': [], - 'installable': False, + 'installable': True, 'images': [], 'auto_install': False, 'license': 'AGPL-3', diff --git a/account_statement_base_import/data/completion_rule_data.xml b/account_statement_base_import/data/completion_rule_data.xml new file mode 100644 index 00000000..d9d738b4 --- /dev/null +++ b/account_statement_base_import/data/completion_rule_data.xml @@ -0,0 +1,22 @@ + + + + + Match from line label (based on partner field 'Bank Statement Label') + 60 + get_from_name_and_partner_field + + + + Match from line label (based on partner name) + 70 + get_from_name_and_partner_name + + + + Match from line reference (based on Invoice reference) + 40 + get_from_ref_and_invoice + + + diff --git a/account_statement_base_import/models/__init__.py b/account_statement_base_import/models/__init__.py new file mode 100644 index 00000000..6a897165 --- /dev/null +++ b/account_statement_base_import/models/__init__.py @@ -0,0 +1,24 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2011-2012 Camptocamp SA +# Copyright 2013 Savoir-faire Linux () +# +# 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 . +# +############################################################################## +from . import account_journal +from . import account_move +from . import partner diff --git a/account_statement_base_import/models/account_journal.py b/account_statement_base_import/models/account_journal.py new file mode 100644 index 00000000..5ee7941c --- /dev/null +++ b/account_statement_base_import/models/account_journal.py @@ -0,0 +1,281 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Joel Grand-Guillaume +# Copyright 2011-2012 Camptocamp SA +# +# 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 . +# +############################################################################## +import sys +import traceback +from openerp import _, api, fields, models +from ..parser.parser import new_move_parser +from openerp.exceptions import UserError, ValidationError +from operator import attrgetter + + +class AccountJournal(models.Model): + _name = 'account.journal' + _inherit = ['account.journal', 'mail.thread'] + + def _get_import_type_selection(self): + """This is the method to be inherited for adding the parser""" + return [('generic_csvxls_so', 'Generic .csv/.xls based on SO Name')] + + def __get_import_type_selection(self): + """ Call method which can be inherited """ + return self._get_import_type_selection() + + commission_account_id = fields.Many2one( + comodel_name='account.account', + string='Commission account') + + import_type = fields.Selection( + __get_import_type_selection, + string='Type of import', + default='generic_csvxls_so', + required=True, + help="Choose here the method by which you want to import bank" + "statement for this profile.") + + last_import_date = fields.Datetime( + string="Last Import Date") + + launch_import_completion = fields.Boolean( + string="Launch completion after import", + help="Tic that box to automatically launch the completion " + "on each imported file using this profile.") + + partner_id = fields.Many2one( + comodel_name='res.partner', + string='Bank/Payment Office partner', + help="Put a partner if you want to have it on the commission move " + "(and optionaly on the counterpart of the intermediate/" + "banking move if you tick the corresponding checkbox).") + + receivable_account_id = fields.Many2one( + comodel_name='account.account', + string='Force Receivable/Payable Account', + help="Choose a receivable account to force the default " + "debit/credit account (eg. an intermediat bank account " + "instead of default debitors).") + + rule_ids = fields.Many2many( + comodel_name='account.move.completion.rule', + string='Auto-completion rules', + rel='as_rul_st_prof_rel') + + def _get_rules(self): + # We need to respect the sequence order + return sorted(self.rule_ids, key=attrgetter('sequence')) + + def _find_values_from_rules(self, calls, line): + """This method will execute all related rules, in their sequence order, + to retrieve all the values returned by the first rules that will match. + :param calls: list of lookup function name available in rules + :param dict line: read of the concerned account.bank.statement.line + :return: + A dict of value that can be passed directly to the write method of + the statement line or {} + {'partner_id': value, + 'account_id: value, + ...} + """ + if not calls: + calls = self._get_rules() + rule_obj = self.env['account.move.completion.rule'] + for call in calls: + method_to_call = getattr(rule_obj, call.function_to_call) + result = method_to_call(line) + if result: + result['already_completed'] = True + return result + return None + + @api.multi + def _write_extra_move_lines(self, parser, move): + """Insert extra lines after the main statement lines. + + After the main statement lines have been created, you can override this + method to create extra statement lines. + + :param: browse_record of the current parser + :param: result_row_list: [{'key':value}] + :param: profile: browserecord of account.statement.profile + :param: statement_id: int/long of the current importing + statement ID + :param: context: global context + """ + move_line_obj = self.env['account.move.line'] + global_commission_amount = 0 + total_amount = 0 + for row in parser.result_row_list: + global_commission_amount += float( + row.get('commission_amount', '0.0')) + total_amount += float( + row.get('amount', '0.0')) + total_amount += global_commission_amount + partner_id = self.partner_id.id + # Commission line + if global_commission_amount < 0.0: + commission_account_id = self.commission_account_id.id + comm_values = { + 'name': _('Commission line'), + 'date_maturity': parser.get_move_vals().get('date') or + fields.Date.today(), + 'debit': -global_commission_amount, + 'partner_id': partner_id, + 'move_id': move.id, + 'account_id': commission_account_id, + 'already_completed': True, + } + move_line_obj.with_context(check_move_validity=False).create(comm_values) + # Counterpart line + if total_amount > 0.0: + receivable_account_id = self.receivable_account_id.id or False + counterpart_values = { + 'name': _('Counterpart line'), + 'date_maturity': parser.get_move_vals().get('date') or + fields.Date.today(), + 'debit': total_amount, + 'partner_id': partner_id, + 'move_id': move.id, + 'account_id': receivable_account_id, + 'already_completed': True, + } + move_line_obj.create(counterpart_values) + + @api.multi + def write_logs_after_import(self, move, num_lines): + """Write the log in the logger + + :param int/long statement_id: ID of the concerned + account.bank.statement + :param int/long num_lines: Number of line that have been parsed + :return: True + """ + self.message_post( + body=_('Move %s have been imported with %s ' + 'lines.') % (move.name, num_lines)) + return True + + def prepare_move_line_vals(self, parser_vals, move): + """Hook to build the values of a line from the parser returned values. + At least it fullfill the statement_id. Overide it to add your own + completion if needed. + + :param dict of vals from parser for account.bank.statement.line + (called by parser.get_st_line_vals) + :param int/long statement_id: ID of the concerned + account.bank.statement + :return: dict of vals that will be passed to create method of + statement line. + """ + move_line_obj = self.env['account.move.line'] + values = parser_vals + values['company_id'] = self.company_id.id + values['journal_id'] = self.id + values['move_id'] = move.id + if values['credit'] > 0.0: + values['account_id'] = self.default_credit_account_id.id + else: + values['account_id'] = self.default_debit_account_id.id + values = move_line_obj._add_missing_default_values(values) + return values + + def prepare_move_vals(self, result_row_list, parser): + """Hook to build the values of the statement from the parser and + the profile. + """ + vals = {'journal_id': self.id} + vals.update(parser.get_move_vals()) + return vals + + def multi_move_import(self, file_stream, ftype="csv"): + """Create multiple bank statements from values given by the parser for + the given profile. + + :param int/long profile_id: ID of the profile used to import the file + :param filebuffer file_stream: binary of the providen file + :param char: ftype represent the file exstension (csv by default) + :return: list: list of ids of the created account.bank.statemênt + """ + parser = new_move_parser(self, ftype=ftype) + res = [] + for result_row_list in parser.parse(file_stream): + move = self._move_import(parser, file_stream, ftype=ftype) + res.append(move) + return res + + def _move_import(self, parser, file_stream, ftype="csv"): + """Create a bank statement with the given profile and parser. It will + fullfill the bank statement with the values of the file providen, but + will not complete data (like finding the partner, or the right + account). This will be done in a second step with the completion rules. + + :param prof : The profile used to import the file + :param parser: the parser + :param filebuffer file_stream: binary of the providen file + :param char: ftype represent the file exstension (csv by default) + :return: ID of the created account.bank.statemênt + """ + move_obj = self.env['account.move'] + move_line_obj = self.env['account.move.line'] + attachment_obj = self.env['ir.attachment'] + result_row_list = parser.result_row_list + # Check all key are present in account.bank.statement.line!! + if not result_row_list: + raise UserError(_("Nothing to import: " + "The file is empty")) + parsed_cols = parser.get_move_line_vals(result_row_list[0]).keys() + for col in parsed_cols: + if col not in move_line_obj._columns: + raise UserError( + _("Missing column! Column %s you try to import is not " + "present in the bank statement line!") % col) + move_vals = self.prepare_move_vals(result_row_list, parser) + move = move_obj.create(move_vals) + try: + # Record every line in the bank statement + move_store = [] + for line in result_row_list: + parser_vals = parser.get_move_line_vals(line) + values = self.prepare_move_line_vals(parser_vals, move) + move_store.append(values) + # Hack to bypass ORM poor perfomance. Sob... + move_line_obj._insert_lines(move_store) + self._write_extra_move_lines(parser, move) + attachment_data = { + 'name': 'statement file', + 'datas': file_stream, + 'datas_fname': "%s.%s" % (fields.Date.today(), ftype), + 'res_model': 'account.move', + 'res_id': move.id, + } + attachment_obj.create(attachment_data) + # If user ask to launch completion at end of import, do it! + if self.launch_import_completion: + move.button_auto_completion() + # Write the needed log infos on profile + self.write_logs_after_import(move, len(result_row_list)) + except Exception: + error_type, error_value, trbk = sys.exc_info() + st = "Error: %s\nDescription: %s\nTraceback:" % ( + error_type.__name__, error_value) + st += ''.join(traceback.format_tb(trbk, 30)) + raise ValidationError( + _("Statement import error" + "The statement cannot be created: %s") % st) + return move diff --git a/account_statement_base_import/models/account_move.py b/account_statement_base_import/models/account_move.py new file mode 100644 index 00000000..edfa2f53 --- /dev/null +++ b/account_statement_base_import/models/account_move.py @@ -0,0 +1,392 @@ +# -*- coding: utf-8 -*- +############################################################################## +# +# Author: Nicolas Bessi, Joel Grand-Guillaume +# Copyright 2011-2012 Camptocamp SA +# +# 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 . +# +############################################################################## +# TODO replace customer supplier by package constant +import traceback +import sys +import logging + +import psycopg2 + +from openerp import _, api, fields, models +from openerp.exceptions import ValidationError + + +_logger = logging.getLogger(__name__) + + +class ErrorTooManyPartner(Exception): + """ New Exception definition that is raised when more than one partner is + matched by the completion rule. + """ + + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + + def __repr__(self): + return repr(self.value) + + +class AccountMoveCompletionRule(models.Model): + """This will represent all the completion method that we can have to + fullfill the bank statement lines. You'll be able to extend them in you own + module and choose those to apply for every statement profile. + The goal of a rule is to fullfill at least the partner of the line, but + if possible also the reference because we'll use it in the reconciliation + process. The reference should contain the invoice number or the SO number + or any reference that will be matched by the invoice accounting move. + """ + _name = "account.move.completion.rule" + _order = "sequence asc" + + def _get_functions(self): + """List of available methods for rules. + + Override this to add you own.""" + return [ + ('get_from_ref_and_invoice', + 'From line reference (based on invoice reference)'), + ('get_from_name_and_partner_field', + 'From line name (based on partner field)'), + ('get_from_name_and_partner_name', + 'From line name (based on partner name)') + ] + + def __get_functions(self): + """ Call method which can be inherited """ + return self._get_functions() + + sequence = fields.Integer( + string='Sequence', + help="Lower means parsed first.") + name = fields.Char( + string='Name', + size=128) + journal_ids = fields.Many2many( + comodel_name='account.journal', + rel='as_rul_st_prof_rel', + string='Related journals') + function_to_call = fields.Selection( + __get_functions, + string='Method') + + # Should be private but data are initialised with no update XML + def get_from_ref_and_invoice(self, line): + """Match the partner based on the invoice number and the reference of + the statement line. Then, call the generic get_values_for_line method + to complete other values. If more than one partner matched, raise the + ErrorTooManyPartner error. + + :param dict line: read of the concerned account.bank.statement.line + :return: + A dict of value that can be passed directly to the write method of + the statement line or {} + {'partner_id': value, + 'account_id': value, + ...} + """ + res = {} + inv_obj = self.env['account.invoice'] + + invoices = inv_obj.search([('reference', '=', line.ref.strip())]) + if invoices: + if len(invoices) == 1: + invoice = invoices[0] + partner_id = invoice.commercial_partner_id.id + res = {'partner_id': partner_id} + else: + raise ErrorTooManyPartner( + _('Line named "%s" (Ref:%s) was matched by more than one ' + 'partner while looking on invoices') % + (line.name, line.ref)) + return res + + # Should be private but data are initialised with no update XML + def get_from_name_and_partner_field(self, line): + """ + Match the partner based on the label field of the statement line and + the text defined in the 'bank_statement_label' field of the partner. + Remember that we can have values separated with ; Then, call the + generic get_values_for_line method to complete other values. If more + than one partner matched, raise the ErrorTooManyPartner error. + + :param dict line: read of the concerned account.bank.statement.line + :return: + A dict of value that can be passed directly to the write method of + the statement line or {} + {'partner_id': value, + 'account_id': value, + + ...} + """ + res = {} + partner_obj = self.env['res.partner'] + or_regex = ".*; *%s *;.*" % line.name + sql = ("SELECT id from res_partner" + " WHERE bank_statement_label ~* %s") + self.env.cr.execute(sql, (or_regex, )) + partner_ids = self.env.cr.fetchall() + partners = partner_obj.browse([x[0] for x in partner_ids]) + if partners: + if len(partners) > 1: + msg = (_('Line named "%s" (Ref:%s) was matched by more than ' + 'one partner while looking on partner label: %s') % + (line.name, line.ref, + ','.join([x.name for x in partners]))) + raise ErrorTooManyPartner(msg) + res['partner_id'] = partners[0].id + return res + + def get_from_name_and_partner_name(self, line): + """Match the partner based on the label field of the statement line and + the name of the partner. Then, call the generic get_values_for_line + method to complete other values. If more than one partner matched, + raise the ErrorTooManyPartner error. + + :param dict st_line: read of the concerned account.bank.statement.line + :return: + A dict of value that can be passed directly to the write method of + the statement line or {} + {'partner_id': value, + 'account_id': value, + + ...} + """ + res = {} + # The regexp_replace() escapes the name to avoid false positive + # example: 'John J. Doe (No 1)' is escaped to 'John J\. Doe \(No 1\)' + # See http://stackoverflow.com/a/400316/1504003 for a list of + # chars to escape. Postgres is POSIX-ARE, compatible with + # POSIX-ERE excepted that '\' must be escaped inside brackets according + # to: + # http://www.postgresql.org/docs/9.0/static/functions-matching.html + # in chapter 9.7.3.6. Limits and Compatibility + sql = r""" + SELECT id FROM ( + SELECT id, + regexp_matches(%s, + regexp_replace(name,'([\.\^\$\*\+\?\(\)\[\{\\\|])', %s, + 'g'), 'i') AS name_match + FROM res_partner) + AS res_partner_matcher + WHERE name_match IS NOT NULL""" + self.env.cr.execute(sql, (line.name, r"\\\1")) + result = self.env.cr.fetchall() + if result: + if len(result) > 1: + raise ErrorTooManyPartner( + _('Line named "%s" (Ref:%s) was matched by more than one ' + 'partner while looking on partner by name') % + (line.name, line.ref)) + res['partner_id'] = result[0][0] + return res + + +class AccountMoveLine(models.Model): + """ + Add sparse field on the statement line to allow to store all the bank infos + that are given by a bank/office. You can then add you own in your module. + The idea here is to store all bank/office infos in the + additionnal_bank_fields serialized field when importing the file. If many + values, add a tab in the bank statement line to store your specific one. + Have a look in account_statement_base_import module to see how we've done + it. + """ + _inherit = "account.move.line" + _order = "already_completed desc, date asc" + + already_completed = fields.Boolean( + string="Auto-Completed", + default=False, + help="When this checkbox is ticked, the auto-completion " + "process/button will ignore this line.") + + def _get_line_values_from_rules(self, line, rules): + """We'll try to find out the values related to the line based on rules + setted on the profile.. We will ignore line for which already_completed + is ticked. + + :return: + A dict of dict value that can be passed directly to the write + method of the statement line or {}. The first dict has statement + line ID as a key: {117009: {'partner_id': 100997, + 'account_id': 489L}} + """ + journal_obj = self.env['account.journal'] + if not line.already_completed: + # Ask the rule + vals = journal_obj._find_values_from_rules(rules, line) + if vals: + vals['id'] = line['id'] + return vals + return {} + + def _get_available_columns(self, move_store): + """Return writeable by SQL columns""" + model_cols = self._columns + avail = [ + k for k, col in model_cols.iteritems() if not hasattr(col, '_fnct') + ] + keys = [k for k in move_store[0].keys() if k in avail] + keys.sort() + return keys + + def _prepare_insert(self, move, cols): + """ Apply column formating to prepare data for SQL inserting + Return a copy of statement + """ + move_copy = move + for k, col in move_copy.iteritems(): + if k in cols: + move_copy[k] = self._columns[k]._symbol_set[1](col) + return move_copy + + def _prepare_manyinsert(self, move_store, cols): + """ Apply column formating to prepare multiple SQL inserts + Return a copy of statement_store + """ + values = [] + for move in move_store: + values.append(self._prepare_insert(move, cols)) + return values + + def _insert_lines(self, move_store): + """ Do raw insert into database because ORM is awfully slow + when doing batch write. It is a shame that batch function + does not exist""" + self.check_access_rule('create') + self.check_access_rights('create', raise_exception=True) + cols = self._get_available_columns(move_store) + move_store = self._prepare_manyinsert(move_store, cols) + tmp_vals = (', '.join(cols), ', '.join(['%%(%s)s' % i for i in cols])) + sql = "INSERT INTO account_move_line (%s) " \ + "VALUES (%s);" % tmp_vals + try: + self.env.cr.executemany(sql, tuple(move_store)) + except psycopg2.Error as sql_err: + self.env.cr.rollback() + raise ValidationError(_("ORM bypass error"), + sql_err.pgerror) + + def _update_line(self, vals): + """ Do raw update into database because ORM is awfully slow + when cheking security. + TODO / WARM: sparse fields are skipped by the method. IOW, if your + completion rule update an sparse field, the updated value will never + be stored in the database. It would be safer to call the update method + from the ORM for records updating this kind of fields. + """ + cols = self._get_available_columns([vals]) + vals = self._prepare_insert(vals, cols) + tmp_vals = (', '.join(['%s = %%(%s)s' % (i, i) for i in cols])) + sql = "UPDATE account_move_line " \ + "SET %s where id = %%(id)s;" % tmp_vals + try: + self.env.cr.execute(sql, vals) + except psycopg2.Error as sql_err: + self.env.cr.rollback() + raise ValidationError(_("ORM bypass error"), + sql_err.pgerror) + + +class AccountMove(models.Model): + """We add a basic button and stuff to support the auto-completion + of the bank statement once line have been imported or manually fullfill. + """ + _name = 'account.move' + _inherit = ['account.move', 'mail.thread'] + + completion_logs = fields.Text(string='Completion Log', readonly=True) + + def write_completion_log(self, error_msg, number_imported): + """Write the log in the completion_logs field of the bank statement to + let the user know what have been done. This is an append mode, so we + don't overwrite what already recoded. + + :param int/long stat_id: ID of the account.bank.statement + :param char error_msg: Message to add + :number_imported int/long: Number of lines that have been completed + :return True + """ + user_name = self.env.user.name + number_line = len(self.line_ids) + log = self.completion_logs or "" + completion_date = fields.Datetime.now() + message = (_("%s Account Move %s has %s/%s lines completed by " + "%s \n%s\n%s\n") % (completion_date, self.name, + number_imported, number_line, + user_name, error_msg, log)) + self.write({'completion_logs': message}) + + body = (_('Statement ID %s auto-completed for %s/%s lines completed') % + (self.name, number_imported, number_line)), + self.message_post(body=body) + return True + + @api.multi + def button_auto_completion(self): + """Complete line with values given by rules and tic the + already_completed checkbox so we won't compute them again unless the + user untick them! + """ + move_line_obj = self.env['account.move.line'] + compl_lines = 0 + move_line_obj.check_access_rule('create') + move_line_obj.check_access_rights('create', raise_exception=True) + for move in self: + msg_lines = [] + journal = move.journal_id + rules = journal._get_rules() + res = False + for line in move.line_ids: + try: + res = move_line_obj._get_line_values_from_rules( + line, rules) + if res: + compl_lines += 1 + except ErrorTooManyPartner, exc: + msg_lines.append(repr(exc)) + except Exception, exc: + msg_lines.append(repr(exc)) + error_type, error_value, trbk = sys.exc_info() + st = "Error: %s\nDescription: %s\nTraceback:" % ( + error_type.__name__, error_value) + st += ''.join(traceback.format_tb(trbk, 30)) + _logger.error(st) + if res: + try: + move_line_obj._update_line(res) + except Exception as exc: + msg_lines.append(repr(exc)) + error_type, error_value, trbk = sys.exc_info() + st = "Error: %s\nDescription: %s\nTraceback:" % ( + error_type.__name__, error_value) + st += ''.join(traceback.format_tb(trbk, 30)) + _logger.error(st) + # we can commit as it is not needed to be atomic + # commiting here adds a nice perfo boost + if not compl_lines % 500: + self.env.cr.commit() + msg = u'\n'.join(msg_lines) + self.write_completion_log(msg, compl_lines) + return True diff --git a/account_statement_base_completion/partner.py b/account_statement_base_import/models/partner.py similarity index 68% rename from account_statement_base_completion/partner.py rename to account_statement_base_import/models/partner.py index 3f371c78..8087f5f4 100644 --- a/account_statement_base_completion/partner.py +++ b/account_statement_base_import/models/partner.py @@ -19,21 +19,20 @@ # ########################################################################## -from openerp.osv import orm, fields +from openerp import fields, models -class ResPartner(orm.Model): +class ResPartner(models.Model): """Add a bank label on the partner so that we can use it to match this partner when we found this in a statement line. """ _inherit = 'res.partner' - _columns = { - 'bank_statement_label': fields.char( - 'Bank Statement Label', size=100, - help="Enter the various label found on your bank statement " - "separated by a ; If one of this label is include in the " - "bank statement line, the partner will be automatically " - "filled (as long as you use this method/rules in your " - "statement profile)."), - } + bank_statement_label = fields.Char( + string='Bank Statement Label', + size=100, + help="Enter the various label found on your bank statement " + "separated by a ; If one of this label is include in the " + "bank statement line, the partner will be automatically " + "filled (as long as you use this method/rules in your " + "statement profile).") diff --git a/account_statement_base_import/parser/__init__.py b/account_statement_base_import/parser/__init__.py index cb73080b..14eca092 100644 --- a/account_statement_base_import/parser/__init__.py +++ b/account_statement_base_import/parser/__init__.py @@ -19,7 +19,7 @@ # ############################################################################## -from .parser import new_bank_statement_parser -from .parser import BankStatementImportParser +from .parser import new_move_parser +from .parser import AccountMoveImportParser from . import file_parser from . import generic_file_parser diff --git a/account_statement_base_import/parser/file_parser.py b/account_statement_base_import/parser/file_parser.py index 706e0b2d..eade8486 100644 --- a/account_statement_base_import/parser/file_parser.py +++ b/account_statement_base_import/parser/file_parser.py @@ -18,11 +18,10 @@ # ############################################################################## from openerp.tools.translate import _ -from openerp.osv.orm import except_orm +from openerp.exceptions import UserError import tempfile import datetime -from .parser import BankStatementImportParser -from .parser import UnicodeDictReader +from .parser import AccountMoveImportParser, UnicodeDictReader try: import xlrd except: @@ -35,7 +34,7 @@ def float_or_zero(val): return float(val) if val else 0.0 -class FileParser(BankStatementImportParser): +class FileParser(AccountMoveImportParser): """Generic abstract class for defining parser for .csv, .xls or .xlsx file format. """ @@ -55,8 +54,7 @@ class FileParser(BankStatementImportParser): if ftype in ('csv', 'xls', 'xlsx'): self.ftype = ftype[0:3] else: - raise except_orm( - _('User Error'), + raise UserError( _('Invalid file type %s. Please use csv, xls or xlsx') % ftype) self.conversion_dict = extra_fields self.keys_to_validate = self.conversion_dict.keys() @@ -96,8 +94,7 @@ class FileParser(BankStatementImportParser): parsed_cols = self.result_row_list[0].keys() for col in self.keys_to_validate: if col not in parsed_cols: - raise except_orm(_('Invalid data'), - _('Column %s not present in file') % col) + raise UserError(_('Column %s not present in file') % col) return True def _post(self, *args, **kwargs): @@ -143,9 +140,9 @@ class FileParser(BankStatementImportParser): line[rule] = datetime.datetime.strptime(date_string, '%Y-%m-%d') except ValueError as err: - raise except_orm( - _("Date format is not valid."), - _(" It should be YYYY-MM-DD for column: %s" + raise UserError( + _("Date format is not valid." + " It should be YYYY-MM-DD for column: %s" " value: %s \n \n \n Please check the line with " "ref: %s \n \n Detail: %s") % (rule, line.get(rule, _('Missing')), @@ -154,8 +151,7 @@ class FileParser(BankStatementImportParser): try: line[rule] = conversion_rules[rule](line[rule]) except Exception as err: - raise except_orm( - _('Invalid data'), + raise UserError( _("Value %s of column %s is not valid.\n Please " "check the line with ref %s:\n \n Detail: %s") % (line.get(rule, _('Missing')), rule, @@ -174,9 +170,9 @@ class FileParser(BankStatementImportParser): self._datemode) line[rule] = datetime.datetime(*t_tuple) except Exception as err: - raise except_orm( - _("Date format is not valid"), - _("Please modify the cell formatting to date " + raise UserError( + _("Date format is not valid. " + "Please modify the cell formatting to date " "format for column: %s value: %s\n Please check " "the line with ref: %s\n \n Detail: %s") % (rule, line.get(rule, _('Missing')), @@ -185,8 +181,7 @@ class FileParser(BankStatementImportParser): try: line[rule] = conversion_rules[rule](line[rule]) except Exception as err: - raise except_orm( - _('Invalid data'), + raise UserError( _("Value %s of column %s is not valid.\n Please " "check the line with ref %s:\n \n Detail: %s") % (line.get(rule, _('Missing')), rule, diff --git a/account_statement_base_import/parser/generic_file_parser.py b/account_statement_base_import/parser/generic_file_parser.py index 47e98445..38879aac 100644 --- a/account_statement_base_import/parser/generic_file_parser.py +++ b/account_statement_base_import/parser/generic_file_parser.py @@ -52,7 +52,7 @@ class GenericFileParser(FileParser): """ return parser_name == 'generic_csvxls_so' - def get_st_line_vals(self, line, *args, **kwargs): + def get_move_line_vals(self, line, *args, **kwargs): """ This method must return a dict of vals that can be passed to create method of statement line in order to record it. It is the @@ -70,10 +70,10 @@ class GenericFileParser(FileParser): 'label':value, } """ + amount = line.get('amount', 0.0) return { 'name': line.get('label', line.get('ref', '/')), - 'date': line.get('date', datetime.datetime.now().date()), - 'amount': line.get('amount', 0.0), - 'ref': line.get('ref', '/'), - 'label': line.get('label', ''), + 'date_maturity': line.get('date', datetime.datetime.now().date()), + 'credit': amount > 0.0 and amount or 0.0, + 'debit': amount < 0.0 and amount or 0.0, } diff --git a/account_statement_base_import/parser/parser.py b/account_statement_base_import/parser/parser.py index 999be4b0..a38a8620 100644 --- a/account_statement_base_import/parser/parser.py +++ b/account_statement_base_import/parser/parser.py @@ -20,8 +20,7 @@ ############################################################################## import base64 import csv -from datetime import datetime -from openerp.tools.translate import _ +from openerp import _, fields def UnicodeDictReader(utf8_data, **kwargs): @@ -41,7 +40,7 @@ def UnicodeDictReader(utf8_data, **kwargs): for key, value in row.iteritems()]) -class BankStatementImportParser(object): +class AccountMoveImportParser(object): """ Generic abstract class for defining parser for different files and @@ -50,21 +49,19 @@ class BankStatementImportParser(object): from the FileParser instead. """ - def __init__(self, profile, *args, **kwargs): + def __init__(self, journal, *args, **kwargs): # The name of the parser as it will be called - self.parser_name = profile.import_type + self.parser_name = journal.import_type # The result as a list of row. One row per line of data in the file, # but not the commission one! self.result_row_list = None # The file buffer on which to work on self.filebuffer = None # The profile record to access its parameters in any parser method - self.profile = profile - self.balance_start = None - self.balance_end = None - self.statement_name = None - self.statement_date = None - self.support_multi_statements = False + self.journal = journal + self.move_date = None + self.move_name = None + self.move_ref= None @classmethod def parser_for(cls, parser_name): @@ -119,19 +116,18 @@ class BankStatementImportParser(object): """ return NotImplementedError - def get_st_vals(self): + def get_move_vals(self): """This method return a dict of vals that ca be passed to create method of statement. :return: dict of vals that represent additional infos for the statement """ return { - 'name': self.statement_name or '/', - 'balance_start': self.balance_start, - 'balance_end_real': self.balance_end, - 'date': self.statement_date or datetime.now() + 'name': self.move_name or '/', + 'date': self.move_date or fields.Datetime.now(), + 'ref': self.move_ref or '/' } - def get_st_line_vals(self, line, *args, **kwargs): + def get_move_line_vals(self, line, *args, **kwargs): """Implement a method in your parser that must return a dict of vals that can be passed to create method of statement line in order to record it. It is the responsibility of every parser to give this dict @@ -165,16 +161,10 @@ class BankStatementImportParser(object): raise Exception(_('No buffer file given.')) self._format(*args, **kwargs) self._pre(*args, **kwargs) - if self.support_multi_statements: - while self._parse(*args, **kwargs): - self._validate(*args, **kwargs) - self._post(*args, **kwargs) - yield self.result_row_list - else: - self._parse(*args, **kwargs) - self._validate(*args, **kwargs) - self._post(*args, **kwargs) - yield self.result_row_list + self._parse(*args, **kwargs) + self._validate(*args, **kwargs) + self._post(*args, **kwargs) + yield self.result_row_list def itersubclasses(cls, _seen=None): @@ -218,13 +208,13 @@ def itersubclasses(cls, _seen=None): yield sub -def new_bank_statement_parser(profile, *args, **kwargs): +def new_move_parser(journal, *args, **kwargs): """Return an instance of the good parser class based on the given profile. :param profile: browse_record of import profile. :return: class instance for given profile import type. """ - for cls in itersubclasses(BankStatementImportParser): - if cls.parser_for(profile.import_type): - return cls(profile, *args, **kwargs) + for cls in itersubclasses(AccountMoveImportParser): + if cls.parser_for(journal.import_type): + return cls(journal, *args, **kwargs) raise ValueError diff --git a/account_statement_base_import/statement.py b/account_statement_base_import/statement.py deleted file mode 100644 index 83e250f3..00000000 --- a/account_statement_base_import/statement.py +++ /dev/null @@ -1,255 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2011-2012 Camptocamp SA -# -# 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 . -# -############################################################################## -import sys -import traceback -from openerp.tools.translate import _ -import datetime -from openerp.osv import fields, orm -from .parser import new_bank_statement_parser -from openerp.tools.config import config - - -class AccountStatementProfil(orm.Model): - _inherit = "account.statement.profile" - - def _get_import_type_selection(self, cr, uid, context=None): - """This is the method to be inherited for adding the parser""" - return [('generic_csvxls_so', 'Generic .csv/.xls based on SO Name')] - - def __get_import_type_selection(self, cr, uid, context=None): - """ Call method which can be inherited """ - return self._get_import_type_selection(cr, uid, context=context) - - _columns = { - 'launch_import_completion': fields.boolean( - "Launch completion after import", - help="Tic that box to automatically launch the completion " - "on each imported file using this profile."), - 'last_import_date': fields.datetime("Last Import Date"), - # we remove deprecated as it floods logs in standard/warning level - # sob... - 'rec_log': fields.text('log', readonly=True), # Deprecated - 'import_type': fields.selection( - __get_import_type_selection, - 'Type of import', - required=True, - help="Choose here the method by which you want to import bank" - "statement for this profile."), - } - - _defaults = { - 'import_type': 'generic_csvxls_so' - } - - def _write_extra_statement_lines( - self, cr, uid, parser, result_row_list, profile, statement_id, - context): - """Insert extra lines after the main statement lines. - - After the main statement lines have been created, you can override this - method to create extra statement lines. - - :param: browse_record of the current parser - :param: result_row_list: [{'key':value}] - :param: profile: browserecord of account.statement.profile - :param: statement_id: int/long of the current importing - statement ID - :param: context: global context - """ - - def write_logs_after_import(self, cr, uid, ids, statement_id, num_lines, - context): - """Write the log in the logger - - :param int/long statement_id: ID of the concerned - account.bank.statement - :param int/long num_lines: Number of line that have been parsed - :return: True - """ - self.message_post( - cr, uid, ids, - body=_('Statement ID %s have been imported with %s ' - 'lines.') % (statement_id, num_lines), context=context) - return True - - # Deprecated remove on V8 - def prepare_statetement_lines_vals(self, *args, **kwargs): - return self.prepare_statement_lines_vals(*args, **kwargs) - - def prepare_statement_lines_vals(self, cr, uid, parser_vals, - statement_id, context): - """Hook to build the values of a line from the parser returned values. - At least it fullfill the statement_id. Overide it to add your own - completion if needed. - - :param dict of vals from parser for account.bank.statement.line - (called by parser.get_st_line_vals) - :param int/long statement_id: ID of the concerned - account.bank.statement - :return: dict of vals that will be passed to create method of - statement line. - """ - statement_line_obj = self.pool['account.bank.statement.line'] - values = parser_vals - values['statement_id'] = statement_id - date = values.get('date') - period_memoizer = context.get('period_memoizer') - if not period_memoizer: - period_memoizer = {} - context['period_memoizer'] = period_memoizer - if period_memoizer.get(date): - values['period_id'] = period_memoizer[date] - else: - # This is awfully slow... - periods = self.pool.get('account.period').find( - cr, uid, dt=values.get('date'), context=context) - values['period_id'] = periods[0] - period_memoizer[date] = periods[0] - values = statement_line_obj._add_missing_default_values( - cr, uid, values, context) - return values - - def prepare_statement_vals(self, cr, uid, profile_id, result_row_list, - parser, context=None): - """Hook to build the values of the statement from the parser and - the profile. - """ - vals = {'profile_id': profile_id} - vals.update(parser.get_st_vals()) - if vals.get('balance_start') is None: - # Get starting balance from journal balance if parser doesn't - # fill this data, simulating the manual flow - statement_obj = self.pool['account.bank.statement'] - profile = self.browse(cr, uid, profile_id, context=context) - temp = statement_obj.onchange_journal_id( - cr, uid, None, profile.journal_id.id, context=context) - vals['balance_start'] = temp['value'].get('balance_start', False) - return vals - - def multi_statement_import(self, cr, uid, ids, profile_id, file_stream, - ftype="csv", context=None): - """Create multiple bank statements from values given by the parser for - the given profile. - - :param int/long profile_id: ID of the profile used to import the file - :param filebuffer file_stream: binary of the providen file - :param char: ftype represent the file exstension (csv by default) - :return: list: list of ids of the created account.bank.statemênt - """ - prof_obj = self.pool['account.statement.profile'] - if not profile_id: - raise orm.except_orm( - _("No Profile!"), - _("You must provide a valid profile to import a bank " - "statement!")) - prof = prof_obj.browse(cr, uid, profile_id, context=context) - parser = new_bank_statement_parser(prof, ftype=ftype) - res = [] - for result_row_list in parser.parse(file_stream): - statement_id = self._statement_import( - cr, uid, ids, prof, parser, file_stream, ftype=ftype, - context=context) - res.append(statement_id) - return res - - def _statement_import(self, cr, uid, ids, prof, parser, file_stream, - ftype="csv", context=None): - """Create a bank statement with the given profile and parser. It will - fullfill the bank statement with the values of the file providen, but - will not complete data (like finding the partner, or the right - account). This will be done in a second step with the completion rules. - - :param prof : The profile used to import the file - :param parser: the parser - :param filebuffer file_stream: binary of the providen file - :param char: ftype represent the file exstension (csv by default) - :return: ID of the created account.bank.statemênt - """ - statement_obj = self.pool['account.bank.statement'] - statement_line_obj = self.pool['account.bank.statement.line'] - attachment_obj = self.pool['ir.attachment'] - result_row_list = parser.result_row_list - # Check all key are present in account.bank.statement.line!! - if not result_row_list: - raise orm.except_orm(_("Nothing to import"), - _("The file is empty")) - parsed_cols = parser.get_st_line_vals(result_row_list[0]).keys() - for col in parsed_cols: - if col not in statement_line_obj._columns: - raise orm.except_orm( - _("Missing column!"), - _("Column %s you try to import is not present in the bank " - "statement line!") % col) - statement_vals = self.prepare_statement_vals( - cr, uid, prof.id, result_row_list, parser, context) - statement_id = statement_obj.create( - cr, uid, statement_vals, context=context) - try: - # Record every line in the bank statement - statement_store = [] - for line in result_row_list: - parser_vals = parser.get_st_line_vals(line) - values = self.prepare_statement_lines_vals( - cr, uid, parser_vals, statement_id, - context) - statement_store.append(values) - # Hack to bypass ORM poor perfomance. Sob... - statement_line_obj._insert_lines( - cr, uid, statement_store, context=context) - self._write_extra_statement_lines( - cr, uid, parser, result_row_list, prof, statement_id, context) - # Trigger store field computation if someone has better idea - start_bal = statement_obj.read( - cr, uid, statement_id, ['balance_start'], context=context) - start_bal = start_bal['balance_start'] - statement_obj.write( - cr, uid, [statement_id], {'balance_start': start_bal}) - attachment_data = { - 'name': 'statement file', - 'datas': file_stream, - 'datas_fname': "%s.%s" % (datetime.datetime.now().date(), - ftype), - 'res_model': 'account.bank.statement', - 'res_id': statement_id, - } - attachment_obj.create(cr, uid, attachment_data, context=context) - # If user ask to launch completion at end of import, do it! - if prof.launch_import_completion: - statement_obj.button_auto_completion( - cr, uid, [statement_id], context) - # Write the needed log infos on profile - self.write_logs_after_import(cr, uid, prof.id, - statement_id, - len(result_row_list), - context) - except Exception: - error_type, error_value, trbk = sys.exc_info() - st = "Error: %s\nDescription: %s\nTraceback:" % ( - error_type.__name__, error_value) - st += ''.join(traceback.format_tb(trbk, 30)) - # TODO we should catch correctly the exception with a python - # Exception and only re-catch some special exception. - # For now we avoid re-catching error in debug mode - if config['debug_mode']: - raise - raise orm.except_orm(_("Statement import error"), - _("The statement cannot be created: %s") % st) - return statement_id diff --git a/account_statement_base_import/statement_view.xml b/account_statement_base_import/statement_view.xml deleted file mode 100644 index b73e0dc7..00000000 --- a/account_statement_base_import/statement_view.xml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - - account.statement.profile.view - account.statement.profile - - - - - - - - + + + + + + + + + + + diff --git a/account_statement_base_import/views/journal_view.xml b/account_statement_base_import/views/journal_view.xml new file mode 100644 index 00000000..fecfca31 --- /dev/null +++ b/account_statement_base_import/views/journal_view.xml @@ -0,0 +1,32 @@ + + + + account.journal.view + account.journal + + + + + + + + + + + + + + + + - - - - - - - - - - - - account_bank_statement_import_base.bank_statement.auto_cmpl - account.bank.statement - - - - - - - - - - - - account.statement.profile.view - account.statement.profile - - - - - - - - - - - - account.statement.completion.rule.view - account.statement.completion.rule - - - - - - - - - - - - - account.statement.completion.rule.view - account.statement.completion.rule - - - - - - - - - - - Statement Completion Rule - account.statement.completion.rule - form - tree,form - - - - - - diff --git a/account_statement_base_completion/test/completion_test.yml b/account_statement_base_completion/test/completion_test.yml deleted file mode 100644 index 5f5cdbad..00000000 --- a/account_statement_base_completion/test/completion_test.yml +++ /dev/null @@ -1,102 +0,0 @@ -- - In order to test the banking framework, I first need to create a profile -- - !record {model: account.statement.profile, id: profile_test1}: - name: Bank EUR Profile - journal_id: account.bank_journal - commission_account_id: account.a_expense - company_id: base.main_company - balance_check: True - rule_ids: - - bank_statement_completion_rule_4 - - bank_statement_completion_rule_5 - - bank_statement_completion_rule_2 - - bank_statement_completion_rule_3 -- - Now I create a statement. I create statment lines separately because I need - to find each one by XML id -- - !record {model: account.bank.statement, id: statement_test1}: - name: Statement 2 - profile_id: profile_test1 - company_id: base.main_company -- - I create a statement line for a CI -- - !record {model: account.bank.statement.line, id: statement_line_ci}: - name: Test autocompletion based on Customer Invoice Number - statement_id: statement_test1 - ref: CI0001 - date: '2013-12-20' - amount: 210.0 -- - I create a statement line for a SI -- - !record {model: account.bank.statement.line, id: statement_line_si}: - name: Test autocompletion based on Supplier Invoice Number - statement_id: statement_test1 - ref: T2S12345 - date: '2013-12-19' - amount: -65.0 -- - I create a statement line for a CR -- - !record {model: account.bank.statement.line, id: statement_line_cr}: - name: Test autocompletion based on Customer Refund Number - statement_id: statement_test1 - ref: CR0001 - date: '2013-12-19' - amount: -210.0 -- - I create a statement line for the Partner Name -- - !record {model: account.bank.statement.line, id: statement_line_partner_name}: - name: Test autocompletion based on Partner Name Vauxoo - statement_id: statement_test1 - ref: / - date: '2013-12-17' - amount: 600.0 -- - I create a statement line for the Partner Label -- - !record {model: account.bank.statement.line, id: statement_line_partner_label}: - name: test autocompletion based on text (XXX66Z) matching with partner form information (note that Ref does not exist) - statement_id: statement_test1 - ref: ZU788 - date: '2013-12-24' - amount: -932.4 -- - I run the auto complete -- - !python {model: account.bank.statement}: | - result = self.button_auto_completion(cr, uid, [ref("statement_test1")]) -- - Now I can check that all is nice and shiny, line 1. I expect the Customer - Invoice Number to be recognised. - I Use _ref, because ref conflicts with the field ref of the statement line -- - !assert {model: account.bank.statement.line, id: statement_line_ci, string: Check completion by CI number}: - - partner_id.id == _ref("base.res_partner_12") -- - Line 2. I expect the Supplier invoice number to be recognised. The supplier - invoice was created by the account module demo data, and we confirmed it - here. -- - !assert {model: account.bank.statement.line, id: statement_line_si, string: Check completion by SI number}: - - partner_id.id == _ref("base.res_partner_17") -- - Line 3. I expect the Customer refund number to be recognised. It should be - the commercial partner, and not the regular partner. -- - !assert {model: account.bank.statement.line, id: statement_line_cr, string: Check completion by CR number and commercial partner}: - - partner_id.id == _ref("base.res_partner_12") -- - Line 4. I check that the partner name has been recognised. -- - !assert {model: account.bank.statement.line, id: statement_line_partner_name, string: Check completion by partner name}: - - partner_id.name == 'Vauxoo' -- - Line 5. I check that the partner special label has been recognised. -- - !assert {model: account.bank.statement.line, id: statement_line_partner_label, string: Check completion by partner label}: - - partner_id.id == _ref("base.res_partner_6") diff --git a/account_statement_base_completion/test/invoice.yml b/account_statement_base_completion/test/invoice.yml deleted file mode 100644 index 5619f0cd..00000000 --- a/account_statement_base_completion/test/invoice.yml +++ /dev/null @@ -1,32 +0,0 @@ -- - I create a customer Invoice to be found by the completion. -- - !record {model: account.invoice, id: invoice_for_completion_1}: - account_id: account.a_recv - company_id: base.main_company - currency_id: base.EUR - internal_number: CI0001 - invoice_line: - - account_id: account.a_sale - name: '[PCSC234] PC Assemble SC234' - price_unit: 210.0 - quantity: 1.0 - product_id: product.product_product_3 - uos_id: product.product_uom_unit - journal_id: account.bank_journal - partner_id: base.res_partner_12 - reference_type: none -- - I confirm the Invoice -- - !workflow {model: account.invoice, action: invoice_open, ref: invoice_for_completion_1} -- - I check that the invoice state is "Open" -- - !assert {model: account.invoice, id: invoice_for_completion_1}: - - state == 'open' -- - I check that it is given the number "CI0001" -- - !assert {model: account.invoice, id: invoice_for_completion_1, string: Check CI number}: - - number == 'CI0001' diff --git a/account_statement_base_completion/tests/__init__.py b/account_statement_base_completion/tests/__init__.py deleted file mode 100644 index 6f9e09ea..00000000 --- a/account_statement_base_completion/tests/__init__.py +++ /dev/null @@ -1,27 +0,0 @@ -# -*- coding: utf-8 -*- -# -# -# Authors: Laurent Mignon -# Copyright (c) 2014 Acsone SA/NV (http://www.acsone.eu) -# All Rights Reserved -# -# 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 . -# -# - -from . import test_base_completion - -checks = [ - test_base_completion -] diff --git a/account_statement_base_import/README.rst b/account_statement_base_import/README.rst new file mode 100644 index 00000000..a4778540 --- /dev/null +++ b/account_statement_base_import/README.rst @@ -0,0 +1,102 @@ +.. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 + +============================= +Account statement base import +============================= + +This module is a grouping of 7.0/8.0 modules, used to import accounting files +and completing them automatically: + +* account_statement_base_completion +* account_statement_base_import +* account_statement_commission +* account_statement_ext + +The main change is that, in order to import financial data, this information +is now imported directly as a Journal Entry. + +Most of the information present in the "statement profile" is now located in +the account journal (with an added boolean parameter which allows to use +this journal for importation). + +Financial data can be imported using a standard .csv or .xls file (you'll find +it in the 'data' folder). It respects the journal to pass the entries. + +This module can handle a commission taken by the payment office and has the +following format: +* __date__: date of the payment +* __amount__: amount paid in the currency of the journal used in the +importation +* __label__: the comunication given by the payment office, used as +communication in the generated entries. + +Another column which can be used is __commission_amount__, representing +the amount for the commission taken by line. + +Afterwards, the goal is to populate the journal items with information that +the bank or office gave you. For this, completion rules can be specified by +journal. + +Some basic rules are provided in this module: + +1) Match from statement line label (based on partner field 'Bank Statement +Label') +2) Match from statement line label (based on partner name) +3) Match from statement line label (based on Invoice reference) + +Feel free to extend either the importation method, the completion method, or +both. + + +.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas + :alt: Try me on Runbot + :target: https://runbot.odoo-community.org/runbot/{repo_id}/{branch} + +.. repo_id is available in https://github.com/OCA/maintainer-tools/blob/master/tools/repos_with_ids.txt +.. branch is "8.0" for example + +Known issues / Roadmap +====================== + +* ... + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues +`_. 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. + +Credits +======= + +Images +------ + +* Odoo Community Association: `Icon `_. + +Contributors +------------ + +* Joël Grand-Guillaume +* Nicolas Bessi +* Sébastien Beau +* Matthieu Dietrich + +Maintainer +---------- + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +This module is maintained by the OCA. + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +To contribute to this module, please visit https://odoo-community.org. diff --git a/account_statement_base_import/__init__.py b/account_statement_base_import/__init__.py index aadbee9c..d4253a2c 100644 --- a/account_statement_base_import/__init__.py +++ b/account_statement_base_import/__init__.py @@ -1,23 +1,7 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2011-2012 Camptocamp SA -# -# 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 . -# -############################################################################## +# © 2011-2016 Camptocamp SA +# Joel Grand-Guillaume, Nicolas Bessi, Matthieu Dietrich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from . import parser from . import wizard from . import models diff --git a/account_statement_base_import/__openerp__.py b/account_statement_base_import/__openerp__.py index 3612ef25..a13218d2 100644 --- a/account_statement_base_import/__openerp__.py +++ b/account_statement_base_import/__openerp__.py @@ -1,76 +1,31 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# Author: Joel Grand-Guillaume -# Copyright 2011-2012 Camptocamp SA -# -# 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 . -# -############################################################################## +# © 2011-2016 Camptocamp SA +# Joel Grand-Guillaume, Nicolas Bessi, Matthieu Dietrich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -{'name': "Bank statement base import", - 'version': '1.2', - 'author': "Camptocamp,Odoo Community Association (OCA)", - 'maintainer': 'Camptocamp', - 'category': 'Finance', - 'complexity': 'normal', - 'depends': [ - 'account' - ], - 'description': """ - This module brings basic methods and fields on bank statement to deal with - the importation of different bank and offices. A generic abstract method is - defined and an example that gives you a basic way of importing bank statement - through a standard file is provided. - - This module improves the bank statement and allows you to import your bank - transactions with a standard .csv or .xls file (you'll find it in the 'data' - folder). It respects the profile (provided by the accouhnt_statement_ext - module) to pass the entries. That means, you'll have to choose a file format - for each profile. - In order to achieve this it uses the `xlrd` Python module which you will need - to install separately in your environment. - - This module can handle a commission taken by the payment office and has the - following format: - - * __ref__: the SO number, INV number or any matching ref found. It'll be used - as reference in the generated entries and will be useful for reconciliation - process - * __date__: date of the payment - * __amount__: amount paid in the currency of the journal used in the - importation profile - * __label__: the comunication given by the payment office, used as - communication in the generated entries. - - The goal is here to populate the statement lines of a bank statement with the - infos that the bank or office give you. Fell free to inherit from this module - to add your own format. Then, if you need to complete data from there, add - your own account_statement_*_completion module and implement the needed rules. - """, - 'website': 'http://www.camptocamp.com', - 'data': [ - "security/ir.model.access.csv", - "data/completion_rule_data.xml", - "wizard/import_statement_view.xml", - "views/account_move_view.xml", - "views/journal_view.xml", - "views/partner_view.xml", - ], - 'test': [], - 'installable': True, - 'images': [], - 'auto_install': False, - 'license': 'AGPL-3', - } +{ + 'name': "Bank statement base import", + 'version': '9.0.1.0.0', + 'author': "Akretion,Camptocamp,Odoo Community Association (OCA)", + 'category': 'Finance', + 'depends': ['account'], + 'website': 'http://www.camptocamp.com', + 'data': [ + "security/ir.model.access.csv", + "data/completion_rule_data.xml", + "wizard/import_statement_view.xml", + "views/account_move_view.xml", + "views/journal_view.xml", + "views/partner_view.xml", + ], + 'test': [ + 'test/partner.yml', + 'test/invoice.yml', + 'test/supplier_invoice.yml', + 'test/refund.yml', + 'test/completion_test.yml' + ], + 'installable': True, + 'auto_install': False, + 'license': 'AGPL-3', +} diff --git a/account_statement_base_import/data/completion_rule_data.xml b/account_statement_base_import/data/completion_rule_data.xml index b06ac51a..ae1ba858 100644 --- a/account_statement_base_import/data/completion_rule_data.xml +++ b/account_statement_base_import/data/completion_rule_data.xml @@ -14,9 +14,15 @@ - Match from line label (based on Invoice reference) + Match from line label (based on Invoice number) 40 get_from_name_and_invoice + + Match from line label (based on Invoice Supplier number) + 45 + get_from_name_and_supplier_invoice + + diff --git a/account_statement_base_import/data/statement.xls b/account_statement_base_import/data/statement.xls index 53ba58a543a9615691535ad304f41bd975a95eb3..5f5a57b061a3ad1b1879524ffb0f8aeb3013df4f 100644 GIT binary patch literal 7168 zcmeHLYiv|S6h3!%TW)Eg+fqskQZ5Awr7iTK@)B5RizRWPsh}|-!R@jw3)?Pfw~8^w z^7?3x}8i@XRLwI*`@H{?fXP5EfG0rmfP7#IPykE?3V~@r z5l{?F2W9~G05gFSU>0Bivw>1z4loy(2b2NxfdxQ0un?#KDuF6s5wIAj25Nv>pbp@^ z?z2kPm!iH5SPrZJ9so#RWt9o7-MzIe9jBO?As!k4w_N9xUHkyr7THDH zsP~2Z#($O8sx|mD+GZb&bfuPwSi=E3J&Js?ys3K5sC=ceKn(PV!82!6avBZt9#na$ z$|ob&OJZ(CU@U zptLIaC9WJf!B_af#tn@vYaS|b70N5TZ4C{Jz23!-A#E|5nwERLC9YZWD(N7~^z7_q~)aYFAaO0EFIqPua|G)GT(5b=g zSt+jP3R4f!q4e@3^vWdkg-PgH!_qTgMjBo4(!4_5rQ;r(>q*dkgXjV?Q|q6bmuDX@ zFtQQpmA--ThaC{pD>0VtUZ*PadNWm--|JH4l->!dEa=UMJ+7|g0X!(5GXBK1SQqFC zhC+cF(q=FQP0(sd`-?GYf>!q&9F&INIZX#dHXYRDC)vSgD%#4Sk{RW5!Z!?SQ_mfr zJX$|N>tz|I)k$`g&)P?jq01f(OVIl?4|0!`T;s!shfv34IvzUx54?ppr9}nJ^rDck z%@+wEj`nqgdpaYyw*GKON3gp)81CF^(y-BxuQd?DcvTv{fm-W8%^ySXt;=Q%=Hu(v zrvj*0iH|LlgW51XxqFZ&&%wsFK?(GGd1{kxOn39-wXeOc&8xR6dM_yPG>-=-^Rzwa zIpNnlsd%^X zijOj`+1DO0%9{5n0sB>6hQ-vWbanN7TYUlQ`>HPNt-26hU2dx%hmXs`7J2rX?3GHb zQj7D)OHDRo?reER=@4N+5rY>|ZE`&^CDC?ZvJwi6cd$?QZM>d{`zHrwK0AY|H; znd=T(2J1~UCXCG$(%5i8t#%qMZYYh`XQ$m#pI&BAC1SQTgjk%&Y&p>4OlHf8(2H|8 zu`-UCCL795K2rPbkDjx5BDvQhalX&MY~L@jm_u=C;3$SvlZ$hiTrYfMa?x~(<}o@-Dw!#lsBuk?9z^%Ml{Z!iQCSL@7C%55Fn{s*72Lw8}xUDyTfe}qj9%C5Hgl6 zsoKP6I}}iUY;CZu&HUsrdD70|^h}{?bD9kOa96yiLld3pr2{Wrzp-(<`_%KgRLnnp zkxsP;9sGu8|1N->y8*h!{Qw_=LjaHBC_sPu8o;pT9f0n#4`58jFBm$?D**o=;1>kL z6i!YVIVd^*)m!E_KV>rU`~P<849vW~NMw63&|@?N1Cg$vf4em=<#C@LAf7z&3d*7N zKf`A~^dI{wz8u@g)T+t!&viJ?e}4Yxq8aYPN1*@88*em#mNA631+*f73n1J8d8xBx zbaand8q5Fx)cS|qq2U%vTkEr8s7LYdW0&m2S1!*pUkBpfQxs{ZKa3pw1+XdqH1s^=XhBl0cG?qmw5>zA4$vN9Pc^ zAA<_4ff@3!^kDxT`1gVT{jSHqz-{VGNQvN|kT598(*jFA{Y9$#UxKk#fDAv=011Az lhJgA9I=%HQ{TKUR3Hg!aTS~hpUH#kte@$E1FbuaN|8JkruzUaj literal 6656 zcmeHLZ){Ul6hH4zw~oIp41|H>(Lvc*H@YpuAu1be{EHg|(ZslfbX_OKcGYe}jWJdb zjR_JJ6Z}A;#7RO(Obm&Mi3W&Y{0vgFZfF=QlNCM6EOhVm4Vx!xrQbd(FJhLO93}f2Jqd~Y<>q#ZE~nZSYVqZ@C=G29nz0HDbHf1i>JBRG0tv^ zY3cMA#mJ8*GueO60^`|=@16Fi|E3=|fU(X$eLm0sG+;U~1DFXQ1c(=y1rX|)?pqI3%Q4(P@@nd?Haur)TVMXMjo!$@by{c1m;VXIgz z$aqIMfr^gOYby1rbOusQzE$N0?48f?KK;V$8ZwBw+LF;wEXV(Z%|TASZp#< z?~tD>7g2MIl1Cq=Qoc*-Tnx)^X-iI7P!1xG69ezp@pznQzFZ+5_2$dnnY>}x zCf`=IoZHo#ZB(kD1J&^52*}Jo5Pi~>_-Tx!Sf;{PMgbB%UYH0QEkd)u~`0fe&6hSQ|z%9>@4ay80( z>n`l6yKr?)jiY=-e7M{8VuF13NI(l{c6&S5R`8-B) zC(qOwyBV1cNk;lionc%(`iFYeI~djE(fI)U9W7oVzeBh}!av#S z^qbW6P#q1DQP*(Ks-~b)XDD^=JvVavP*$B$P#wnT7+v@Qtkg&9lNd2p-o?urX~dld zrw^TgXbIB){#?-%T<{{!Ro*$s7*IsnT2*N4NgL<6CI)ZbgTfsr#b6pw(~uUc_UlT@1@RYIGGqo^bJ}a&x9i}tGPZ{ zx1D}B7JZK{(tVLVC-UB z+ITEJUQg10!~(bT|BqV#yggiKnmkA;9!$_$_5bOKOl1P;6zn$cH|pdWDpo}m9R)~} zEfN!+_=yqwXTLTTqooEy{8vJ9$wM+EaXcaQ?`;$Q!u7!>NyQnID9ZgA(Sm6;`nPY6 z9792&JmzxL&t-X. -# -############################################################################## +# © 2011-2016 Camptocamp SA +# Joel Grand-Guillaume, Nicolas Bessi, Matthieu Dietrich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). import sys import traceback import os @@ -223,10 +207,10 @@ class AccountJournal(models.Model): if filename: (filename, __) = os.path.splitext(filename) parser = new_move_parser(self, ftype=ftype, move_ref=filename) - res = [] + res = self.env['account.move'] for result_row_list in parser.parse(file_stream): move = self._move_import(parser, file_stream, ftype=ftype) - res.append(move) + res |= move return res def _move_import(self, parser, file_stream, ftype="csv"): diff --git a/account_statement_base_import/models/account_move.py b/account_statement_base_import/models/account_move.py index cc68b393..9266599d 100644 --- a/account_statement_base_import/models/account_move.py +++ b/account_statement_base_import/models/account_move.py @@ -1,23 +1,7 @@ # -*- coding: utf-8 -*- -############################################################################## -# -# Author: Nicolas Bessi, Joel Grand-Guillaume -# Copyright 2011-2012 Camptocamp SA -# -# 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 . -# -############################################################################## +# © 2011-2016 Camptocamp SA +# Joel Grand-Guillaume, Nicolas Bessi, Matthieu Dietrich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). # TODO replace customer supplier by package constant import traceback import sys @@ -65,7 +49,9 @@ class AccountMoveCompletionRule(models.Model): Override this to add you own.""" return [ ('get_from_name_and_invoice', - 'From line name (based on invoice reference)'), + 'From line name (based on customer invoice number)'), + ('get_from_name_and_supplier_invoice', + 'From line name (based on supplier invoice number)'), ('get_from_name_and_partner_field', 'From line name (based on partner field)'), ('get_from_name_and_partner_name', @@ -90,6 +76,62 @@ class AccountMoveCompletionRule(models.Model): __get_functions, string='Method') + def _find_invoice(self, line, inv_type): + """Find invoice related to statement line""" + inv_obj = self.env['account.invoice'] + if inv_type == 'supplier': + type_domain = ('in_invoice', 'in_refund') + number_field = 'reference' + elif inv_type == 'customer': + type_domain = ('out_invoice', 'out_refund') + number_field = 'number' + else: + raise ValidationError( + _('Invalid invoice type for completion: %') % inv_type) + + invoices = inv_obj.search([(number_field, '=', line.name.strip()), + ('type', 'in', type_domain)]) + if invoices: + if len(invoices) == 1: + invoice = invoices[0] + else: + raise ErrorTooManyPartner( + _('Line named "%s" was matched by more than one ' + 'partner while looking on %s invoices') % + (line.name, inv_type)) + return invoice + return False + + def _from_invoice(self, line, inv_type): + """Populate statement line values""" + if inv_type not in ('supplier', 'customer'): + raise ValidationError( + _('Invalid invoice type for completion: %') % + inv_type) + res = {} + invoice = self._find_invoice(line, inv_type) + if invoice: + partner_id = invoice.commercial_partner_id.id + res = {'partner_id': partner_id} + return res + + # Should be private but data are initialised with no update XML + def get_from_name_and_supplier_invoice(self, line): + """Match the partner based on the invoice number and the reference of + the statement line. Then, call the generic get_values_for_line method + to complete other values. If more than one partner matched, raise the + ErrorTooManyPartner error. + + :param dict line: read of the concerned account.bank.statement.line + :return: + A dict of value that can be passed directly to the write method of + the statement line or {} + {'partner_id': value, + 'account_id': value, + ...} + """ + return self._from_invoice(line, 'supplier') + # Should be private but data are initialised with no update XML def get_from_name_and_invoice(self, line): """Match the partner based on the invoice number and the reference of @@ -105,20 +147,7 @@ class AccountMoveCompletionRule(models.Model): 'account_id': value, ...} """ - res = {} - inv_obj = self.env['account.invoice'] - invoices = inv_obj.search([('name', '=', line.name.strip())]) - if invoices: - if len(invoices) == 1: - invoice = invoices[0] - partner_id = invoice.commercial_partner_id.id - res = {'partner_id': partner_id} - else: - raise ErrorTooManyPartner( - _('Line named "%s" (Ref:%s) was matched by more than one ' - 'partner while looking on invoices') % - (line.name)) - return res + return self._from_invoice(line, 'customer') # Should be private but data are initialised with no update XML def get_from_name_and_partner_field(self, line): @@ -140,7 +169,7 @@ class AccountMoveCompletionRule(models.Model): """ res = {} partner_obj = self.env['res.partner'] - or_regex = ".*; *%s *;.*" % line.name + or_regex = ".*;? *%s *;?.*" % line.name sql = ("SELECT id from res_partner" " WHERE bank_statement_label ~* %s") self.env.cr.execute(sql, (or_regex, )) diff --git a/account_statement_base_import/models/partner.py b/account_statement_base_import/models/partner.py index 8087f5f4..9677fa12 100644 --- a/account_statement_base_import/models/partner.py +++ b/account_statement_base_import/models/partner.py @@ -1,24 +1,7 @@ # -*- coding: utf-8 -*- -########################################################################## -# -# Copyright (C) 2011 Akretion & Camptocamp -# Author : Sébastien BEAU, Joel Grand-Guillaume -# -# 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 . -# -########################################################################## - +# © 2011-2016 Camptocamp SA +# Joel Grand-Guillaume, Nicolas Bessi, Matthieu Dietrich +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). from openerp import fields, models diff --git a/account_statement_base_import/test/completion_test.yml b/account_statement_base_import/test/completion_test.yml new file mode 100644 index 00000000..2f020200 --- /dev/null +++ b/account_statement_base_import/test/completion_test.yml @@ -0,0 +1,125 @@ +- + In order to test the banking framework, I first need to create a journal +- + !record {model: account.journal, id: account.bank_journal}: + used_for_import: True + partner_id: base.res_partner_12 + commission_account_id: account.a_expense + receivable_account_id: account.a_expense + rule_ids: + - bank_statement_completion_rule_4 + - bank_statement_completion_rule_2 + - bank_statement_completion_rule_3 + - bank_statement_completion_rule_5 +- + Now I create a statement. I create statment lines separately because I need + to find each one by XML id +- + !record {model: account.move, id: move_test1}: + name: Move 2 + journal_id: account.bank_journal + company_id: base.main_company +- + I create a move line for a CI +- + !record {model: account.move.line, id: move_line_ci}: + name: \ + account_id: account.a_sale + move_id: move_test1 + date_maturity: '2013-12-20' + credit: 0.0 +- + I create a move line for a SI +- + !record {model: account.move.line, id: move_line_si}: + name: \ + account_id: account.a_expense + move_id: move_test1 + date_maturity: '2013-12-19' + debit: 0.0 +- + I create a move line for a CR +- + !record {model: account.move.line, id: move_line_cr}: + name: \ + account_id: account.a_expense + move_id: move_test1 + date_maturity: '2013-12-19' + debit: 0.0 +- + I create a move line for the Partner Name +- + !record {model: account.move.line, id: move_line_partner_name}: + name: Test autocompletion based on Partner Name Camptocamp + account_id: account.a_sale + move_id: move_test1 + date_maturity: '2013-12-17' + credit: 0.0 +- + I create a move line for the Partner Label +- + !record {model: account.move.line, id: move_line_partner_label}: + name: XXX66Z + account_id: account.a_sale + move_id: move_test1 + date_maturity: '2013-12-24' + debit: 0.0 +- + and add the correct name +- + !python {model: account.move.line}: | + import datetime as dt + context['check_move_validity'] = False + model.write(cr, uid, [ref('move_line_ci')], + {'name': dt.date.today().strftime('TBNK/%Y/0001'), + 'credit': 210.0}, + context) + model.write(cr, uid, [ref('move_line_si')], + {'name': 'T2S12345', + 'debit': 65.0}, + context) + model.write(cr, uid, [ref('move_line_cr')], + {'name': dt.date.today().strftime('RTEXJ/%Y/0001'), + 'debit': 210.0}, + context) + model.write(cr, uid, [ref('move_line_partner_name')], + {'credit': 600.0}, + context) + model.write(cr, uid, [ref('move_line_partner_label')], + {'debit': 932.4}, + context) +- + I run the auto complete +- + !python {model: account.move}: | + result = self.button_auto_completion(cr, uid, [ref("move_test1")]) +- + Now I can check that all is nice and shiny, line 1. I expect the Customer + Invoice Number to be recognised. + I Use _ref, because ref conflicts with the field ref of the statement line +- + !assert {model: account.move.line, id: move_line_ci, string: Check completion by CI number}: + - partner_id.id == _ref("base.res_partner_12") +- + Line 2. I expect the Supplier invoice number to be recognised. The supplier + invoice was created by the account module demo data, and we confirmed it + here. +- + !assert {model: account.move.line, id: move_line_si, string: Check completion by SI number}: + - partner_id.id == _ref("base.res_partner_12") +- + Line 3. I expect the Customer refund number to be recognised. It should be + the commercial partner, and not the regular partner. +- + !assert {model: account.move.line, id: move_line_cr, string: Check completion by CR number and commercial partner}: + - partner_id.id == _ref("base.res_partner_12") +- + Line 4. I check that the partner name has been recognised. +- + !assert {model: account.move.line, id: move_line_partner_name, string: Check completion by partner name}: + - partner_id.name == 'Camptocamp' +- + Line 5. I check that the partner special label has been recognised. +- + !assert {model: account.move.line, id: move_line_partner_label, string: Check completion by partner label}: + - partner_id.id == _ref("base.res_partner_4") diff --git a/account_statement_base_import/test/invoice.yml b/account_statement_base_import/test/invoice.yml new file mode 100644 index 00000000..5379f670 --- /dev/null +++ b/account_statement_base_import/test/invoice.yml @@ -0,0 +1,42 @@ +- + I import account minimal data +- + !python {model: account.invoice}: | + openerp.tools.convert_file(cr, + 'account', + openerp.modules.get_module_resource( + 'account', + 'test', + 'account_minimal_test.xml'), + {}, 'init', False, 'test') +- + I create a customer Invoice to be found by the completion. +- + !record {model: account.invoice, id: invoice_for_completion_1}: + company_id: base.main_company + currency_id: base.EUR + invoice_line_ids: + - name: '[PCSC234] PC Assemble SC234' + price_unit: 210.0 + quantity: 1.0 + product_id: product.product_product_3 + uom_id: product.product_uom_unit + journal_id: account.bank_journal + partner_id: base.res_partner_12 + reference_type: none +- + I confirm the Invoice +- + !workflow {model: account.invoice, action: invoice_open, ref: invoice_for_completion_1} +- + I check that the invoice state is "Open" +- + !assert {model: account.invoice, id: invoice_for_completion_1}: + - state == 'open' +- + I check that it is given the number "TBNK/%Y/0001" +- + !python {model: account.invoice}: | + import datetime as dt + invoice = model.browse(cr, uid, ref('invoice_for_completion_1'), context) + assert invoice.number == dt.date.today().strftime('TBNK/%Y/0001') diff --git a/account_statement_base_completion/test/partner.yml b/account_statement_base_import/test/partner.yml similarity index 62% rename from account_statement_base_completion/test/partner.yml rename to account_statement_base_import/test/partner.yml index bc8fca6c..5e207100 100644 --- a/account_statement_base_completion/test/partner.yml +++ b/account_statement_base_import/test/partner.yml @@ -1,5 +1,5 @@ - I fill in the field Bank Statement Label in a Partner - - !record {model: res.partner, id: base.res_partner_6}: + !record {model: res.partner, id: base.res_partner_4}: bank_statement_label: XXX66Z diff --git a/account_statement_base_completion/test/refund.yml b/account_statement_base_import/test/refund.yml similarity index 71% rename from account_statement_base_completion/test/refund.yml rename to account_statement_base_import/test/refund.yml index f8c07909..2779ba73 100644 --- a/account_statement_base_completion/test/refund.yml +++ b/account_statement_base_import/test/refund.yml @@ -12,17 +12,14 @@ I create a customer refund to be found by the completion. - !record {model: account.invoice, id: refund_for_completion_1}: - account_id: account.a_pay company_id: base.main_company currency_id: base.EUR - internal_number: CR0001 - invoice_line: - - account_id: account.a_expense - name: '[PCSC234] PC Assemble SC234' + invoice_line_ids: + - name: '[PCSC234] PC Assemble SC234' price_unit: 210.0 quantity: 1.0 product_id: product.product_product_3 - uos_id: product.product_uom_unit + uom_id: product.product_uom_unit journal_id: account.expenses_journal partner_id: res_partner_12_child type: 'out_refund' @@ -37,7 +34,9 @@ !assert {model: account.invoice, id: refund_for_completion_1}: - state == 'open' - - I check that it is given the number "CR0001" + I check that it is given the number "RTEXJ/%Y/0001" - - !assert {model: account.invoice, id: refund_for_completion_1, string: Check CI number}: - - number == 'CR0001' + !python {model: account.invoice}: | + import datetime as dt + invoice = model.browse(cr, uid, ref('refund_for_completion_1'), context) + assert invoice.number == dt.date.today().strftime('RTEXJ/%Y/0001') diff --git a/account_statement_base_completion/test/supplier_invoice.yml b/account_statement_base_import/test/supplier_invoice.yml similarity index 66% rename from account_statement_base_completion/test/supplier_invoice.yml rename to account_statement_base_import/test/supplier_invoice.yml index 1bd826f9..4ac8e87d 100644 --- a/account_statement_base_completion/test/supplier_invoice.yml +++ b/account_statement_base_import/test/supplier_invoice.yml @@ -1,3 +1,14 @@ +- + I import account minimal data +- + !python {model: account.invoice}: | + openerp.tools.convert_file(cr, + 'account', + openerp.modules.get_module_resource( + 'account', + 'demo', + 'account_invoice_demo.yml'), + {}, 'init', False, 'test') - I check that my invoice is a supplier invoice - @@ -8,7 +19,7 @@ - !python {model: account.invoice}: | self.write(cr, uid, ref('account.demo_invoice_0'), { - 'supplier_invoice_number': 'T2S12345' + 'reference': 'T2S12345' }) - I check a second time that my invoice is still a supplier invoice @@ -23,7 +34,7 @@ I check that the supplier number is there - !assert {model: account.invoice, id: account.demo_invoice_0, string: Check supplier number}: - - supplier_invoice_number == 'T2S12345' + - reference == 'T2S12345' - I check a third time that my invoice is still a supplier invoice - diff --git a/account_statement_base_import/tests/test_base_completion.py b/account_statement_base_import/tests/test_base_completion.py index 9fd9adb5..d48d6769 100644 --- a/account_statement_base_import/tests/test_base_completion.py +++ b/account_statement_base_import/tests/test_base_completion.py @@ -19,8 +19,9 @@ # along with this program. If not, see . # # +from openerp import fields, tools +from openerp.modules import get_module_resource from openerp.tests import common -import time from collections import namedtuple name_completion_case = namedtuple( @@ -51,17 +52,17 @@ class base_completion(common.TransactionCase): def setUp(self): super(base_completion, self).setUp() + tools.convert_file(self.cr, 'account', + get_module_resource('account', 'test', + 'account_minimal_test.xml'), + {}, 'init', False, 'test') + self.account_move_obj = self.env["account.move"] + self.account_move_line_obj = \ + self.env["account.move.line"] self.company_a = self.browse_ref('base.main_company') - self.profile_obj = self.registry("account.statement.profile") - self.partner_obj = self.registry("res.partner") - self.account_bank_statement_obj = self.registry( - "account.bank.statement") - self.account_bank_statement_line_obj = self.registry( - "account.bank.statement.line") - self.journal_id = self.ref("account.bank_journal") - self.partner_id = self.ref('base.main_partner') + self.journal = self.browse_ref("account.bank_journal") + self.partner = self.browse_ref("base.res_partner_12") self.account_id = self.ref("account.a_recv") - self.partner_id = self.ref("base.res_partner_12") def test_name_completion(self): """Test complete partner_id from statement line label @@ -69,54 +70,44 @@ class base_completion(common.TransactionCase): the partner appears in the statement line label """ self.completion_rule_id = self.ref( - 'account_statement_base_completion.' - 'bank_statement_completion_rule_3') + 'account_statement_base_import.bank_statement_completion_rule_3') # Create the profile - self.profile_id = self.profile_obj.create(self.cr, self.uid, { - "name": "TEST", - "commission_account_id": self.account_id, - "journal_id": self.journal_id, - "rule_ids": [(6, 0, [self.completion_rule_id])]}) + self.journal.write({ + 'used_for_import': True, + 'partner_id': self.partner.id, + 'commission_account_id': self.account_id, + 'receivable_account_id': self.account_id, + 'rule_ids': [(6, 0, [self.completion_rule_id])] + }) # Create a bank statement - self.statement_id = self.account_bank_statement_obj.create( - self.cr, self.uid, { - "balance_end_real": 0.0, - "balance_start": 0.0, - "date": time.strftime('%Y-%m-%d'), - "journal_id": self.journal_id, - "profile_id": self.profile_id - }) + self.move = self.account_move_obj.create({ + "date": fields.Date.today(), + "journal_id": self.journal.id + }) for case in NAMES_COMPLETION_CASES: - self.partner_obj.write( - self.cr, self.uid, self.partner_id, {'name': case.partner_name} - ) - statement_line_id = self.account_bank_statement_line_obj.create( - self.cr, self.uid, { - 'amount': 1000.0, - 'name': case.line_label, - 'ref': 'My ref', - 'statement_id': self.statement_id, - }) - statement_line = self.account_bank_statement_line_obj.browse( - self.cr, self.uid, statement_line_id) + self.partner.write({'name': case.partner_name}) + self.move_line = self.account_move_line_obj.with_context( + check_move_validity=False + ).create({ + 'account_id': self.account_id, + 'credit': 1000.0, + 'name': case.line_label, + 'move_id': self.move.id, + }) self.assertFalse( - statement_line.partner_id, + self.move_line.partner_id, "Partner_id must be blank before completion") - statement_obj = self.account_bank_statement_obj.browse( - self.cr, self.uid, self.statement_id) - statement_obj.button_auto_completion() - statement_line = self.account_bank_statement_line_obj.browse( - self.cr, self.uid, statement_line_id) + self.move.button_auto_completion() if case.should_match: self.assertEquals( - self.partner_id, statement_line.partner_id['id'], + self.partner, self.move_line.partner_id, "Missing expected partner id after completion " "(partner_name: %s, line_name: %s)" % (case.partner_name, case.line_label)) else: self.assertNotEquals( - self.partner_id, statement_line.partner_id['id'], + self.partner, self.move_line.partner_id, "Partner id should be empty after completion " "(partner_name: %s, line_name: %s)" % (case.partner_name, case.line_label)) diff --git a/account_statement_base_import/tests/test_base_import.py b/account_statement_base_import/tests/test_base_import.py index eea31069..1b8e1f85 100644 --- a/account_statement_base_import/tests/test_base_import.py +++ b/account_statement_base_import/tests/test_base_import.py @@ -23,38 +23,32 @@ import base64 import inspect import os from openerp.tests import common +from openerp import tools +from openerp.modules import get_module_resource class TestCodaImport(common.TransactionCase): - def prepare(self): + def setUp(self): + super(TestCodaImport, self).setUp() self.company_a = self.browse_ref('base.main_company') - self.profile_obj = self.registry("account.statement.profile") - self.account_bank_statement_obj = self.registry( - "account.bank.statement") - # create the 2009 fiscal year since imported coda file reference - # statement lines in 2009 - self.fiscalyear_id = self._create_fiscalyear("2011", self.company_a.id) + tools.convert_file(self.cr, 'account', + get_module_resource('account', 'test', + 'account_minimal_test.xml'), + {}, 'init', False, 'test') + self.account_move_obj = self.env["account.move"] + self.account_move_line_obj = self.env["account.move.line"] self.account_id = self.ref("account.a_recv") - self.journal_id = self.ref("account.bank_journal") - self.import_wizard_obj = self.registry('credit.statement.import') - self.profile_id = self.profile_obj.create(self.cr, self.uid, { - "name": "BASE_PROFILE", - "commission_account_id": self.account_id, - "journal_id": self.journal_id, - "import_type": "generic_csvxls_so"}) - - def _create_fiscalyear(self, year, company_id): - fiscalyear_obj = self.registry("account.fiscalyear") - fiscalyear_id = fiscalyear_obj.create(self.cr, self.uid, { - "name": year, - "code": year, - "date_start": year + "-01-01", - "date_stop": year + "-12-31", - "company_id": company_id + self.journal = self.browse_ref("account.bank_journal") + self.import_wizard_obj = self.env['credit.statement.import'] + self.partner = self.browse_ref("base.res_partner_12") + self.journal.write({ + 'used_for_import': True, + "import_type": "generic_csvxls_so", + 'partner_id': self.partner.id, + 'commission_account_id': self.account_id, + 'receivable_account_id': self.account_id, }) - fiscalyear_obj.create_period3(self.cr, self.uid, [fiscalyear_id]) - return fiscalyear_id def _filename_to_abs_filename(self, file_name): dir_name = os.path.dirname(inspect.getfile(self.__class__)) @@ -66,45 +60,35 @@ class TestCodaImport(common.TransactionCase): """ with open(file_name) as f: content = f.read() - wizard_id = self.import_wizard_obj.create(self.cr, self.uid, { - "profile_id": self.profile_id, + self.wizard = self.import_wizard_obj.create({ + "journal_id": self.journal.id, 'input_statement': base64.b64encode(content), 'file_name': os.path.basename(file_name), }) - res = self.import_wizard_obj.import_statement( - self.cr, self.uid, wizard_id) - statement_id = self.account_bank_statement_obj.search( - self.cr, self.uid, eval(res['domain'])) - return self.account_bank_statement_obj.browse( - self.cr, self.uid, statement_id)[0] + res = self.wizard.import_statement() + return self.account_move_obj.browse(res['res_id']) def test_simple_xls(self): """Test import from xls """ - self.prepare() file_name = self._filename_to_abs_filename( os.path.join("..", "data", "statement.xls")) - statement = self._import_file(file_name) - self._validate_imported_satement(statement) + move = self._import_file(file_name) + self._validate_imported_move(move) def test_simple_csv(self): """Test import from csv """ - self.prepare() file_name = self._filename_to_abs_filename( os.path.join("..", "data", "statement.csv")) - statement = self._import_file(file_name) - self._validate_imported_satement(statement) + move = self._import_file(file_name) + self._validate_imported_move(move) - def _validate_imported_satement(self, statement): - self.assertEqual("/", statement.name) - self.assertEqual(0.0, statement.balance_start) - self.assertEqual(0.0, statement.balance_end_real) - self.assertEqual(3, len(statement.line_ids)) - self.assertTrue(statement.account_id) - st_line_obj = statement.line_ids[1] + def _validate_imported_move(self, move): + self.assertEqual("/", move.name) + self.assertEqual(5, len(move.line_ids)) + move_line = move.line_ids[4] # common infos - self.assertEqual(st_line_obj.ref, "51065326") - self.assertEqual(st_line_obj.date, "2011-03-02") - self.assertEqual(st_line_obj.amount, 189.0) - self.assertEqual(st_line_obj.name, "label b") + self.assertEqual(move_line.date_maturity, "2011-03-02") + self.assertEqual(move_line.credit, 189.0) + self.assertEqual(move_line.name, "label b") diff --git a/account_statement_base_import/views/journal_view.xml b/account_statement_base_import/views/journal_view.xml index 6e7bbf15..c14dfdd0 100644 --- a/account_statement_base_import/views/journal_view.xml +++ b/account_statement_base_import/views/journal_view.xml @@ -11,14 +11,14 @@ - + - + - - - + + + - + diff --git a/account_statement_base_import/views/journal_view.xml b/account_statement_base_import/views/journal_view.xml index c14dfdd0..d3696218 100644 --- a/account_statement_base_import/views/journal_view.xml +++ b/account_statement_base_import/views/journal_view.xml @@ -7,18 +7,21 @@ + - + - + - - - + + + - + diff --git a/account_statement_base_import/wizard/import_statement.py b/account_statement_base_import/wizard/import_statement.py index d133910a..0c8116eb 100644 --- a/account_statement_base_import/wizard/import_statement.py +++ b/account_statement_base_import/wizard/import_statement.py @@ -39,7 +39,7 @@ class CreditPartnerStatementImporter(models.TransientModel): partner_id = fields.Many2one( comodel_name='res.partner', string='Credit institute partner') - file_name = fields.Char('File Name', size=128) + file_name = fields.Char() receivable_account_id = fields.Many2one( comodel_name='account.account', string='Force Receivable/Payable Account') @@ -59,8 +59,10 @@ class CreditPartnerStatementImporter(models.TransientModel): } } - def _check_extension(self, filename): - (__, ftype) = os.path.splitext(filename) + @api.multi + def _check_extension(self): + self.ensure_one() + (__, ftype) = os.path.splitext(self.file_name) if not ftype: # We do not use osv exception we do not want to have it logged raise Exception(_('Please use a file with an extension')) @@ -72,7 +74,7 @@ class CreditPartnerStatementImporter(models.TransientModel): moves = self.env['account.move'] for importer in self: journal = importer.journal_id - ftype = self._check_extension(importer.file_name) + ftype = importer._check_extension() moves |= journal.with_context( file_name=importer.file_name).multi_move_import( importer.input_statement, diff --git a/account_statement_base_import/wizard/import_statement_view.xml b/account_statement_base_import/wizard/import_statement_view.xml index b975fb1b..dbc4d72b 100644 --- a/account_statement_base_import/wizard/import_statement_view.xml +++ b/account_statement_base_import/wizard/import_statement_view.xml @@ -14,11 +14,10 @@ - - +
+
From 092ff40aa9a90d242924f423c1a07adb64818a16 Mon Sep 17 00:00:00 2001 From: Matthieu Dietrich Date: Fri, 29 Apr 2016 15:41:29 +0200 Subject: [PATCH 18/32] Remove unnecessary checks --- account_statement_bankaccount_completion/tests/__init__.py | 4 ---- account_statement_base_import/tests/__init__.py | 5 ----- 2 files changed, 9 deletions(-) diff --git a/account_statement_bankaccount_completion/tests/__init__.py b/account_statement_bankaccount_completion/tests/__init__.py index 7f2130be..8f905942 100644 --- a/account_statement_bankaccount_completion/tests/__init__.py +++ b/account_statement_bankaccount_completion/tests/__init__.py @@ -2,7 +2,3 @@ # © 2013 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from . import test_bankaccount_completion - -checks = [ - test_bankaccount_completion -] diff --git a/account_statement_base_import/tests/__init__.py b/account_statement_base_import/tests/__init__.py index 3129f6a8..2a150908 100644 --- a/account_statement_base_import/tests/__init__.py +++ b/account_statement_base_import/tests/__init__.py @@ -6,8 +6,3 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from . import test_base_completion from . import test_base_import - -checks = [ - test_base_completion, - test_base_import -] From cd150db4067888199e0df6bc7bdf8393d213645a Mon Sep 17 00:00:00 2001 From: Matthieu Dietrich Date: Tue, 24 May 2016 11:51:51 +0200 Subject: [PATCH 19/32] Remane import modules --- .../README.rst | 0 .../__init__.py | 0 .../__openerp__.py | 2 +- .../data/completion_rule_data.xml | 0 .../account_statement_bankaccount_completion.pot | 0 .../i18n/es.po | 0 .../i18n/fr.po | 0 .../models/__init__.py | 0 .../models/account_move.py | 2 +- .../models/res_partner_bank.py | 0 .../tests/__init__.py | 0 .../tests/test_bankaccount_completion.py | 0 .../README.rst | 0 .../__init__.py | 0 .../__openerp__.py | 0 .../data/completion_rule_data.xml | 0 .../data/statement.csv | 0 .../data/statement.xls | Bin .../i18n/account_statement_base_import.pot | 0 .../i18n/es.po | 0 .../i18n/fr.po | 0 .../models/__init__.py | 0 .../models/account_journal.py | 0 .../models/account_move.py | 2 +- .../models/partner.py | 0 .../parser/__init__.py | 0 .../parser/file_parser.py | 0 .../parser/generic_file_parser.py | 2 +- .../parser/parser.py | 0 .../security/ir.model.access.csv | 0 .../test/completion_test.yml | 0 .../test/invoice.yml | 0 .../test/partner.yml | 0 .../test/refund.yml | 0 .../test/supplier_invoice.yml | 0 .../tests/__init__.py | 0 .../tests/test_base_completion.py | 2 +- .../tests/test_base_import.py | 0 .../views/account_move_view.xml | 0 .../views/journal_view.xml | 0 .../views/partner_view.xml | 0 .../wizard/__init__.py | 0 .../wizard/import_statement.py | 0 .../wizard/import_statement_view.xml | 0 .../README.rst | 0 .../__init__.py | 0 .../__openerp__.py | 2 +- .../data/completion_rule_data.xml | 0 .../i18n/account_statement_so_completion.pot | 0 .../i18n/es.po | 0 .../models/__init__.py | 0 .../models/account_move.py | 2 +- .../test/completion_so_test.yml | 0 .../README.rst | 0 .../__init__.py | 0 .../__openerp__.py | 2 +- .../data/completion_rule_data.xml | 0 .../data/statement.csv | 0 .../data/statement.xls | Bin .../i18n/account_statement_transactionid_import.pot | 0 .../i18n/es.po | 0 .../models/__init__.py | 0 .../models/account_journal.py | 0 .../models/account_move.py | 2 +- .../parser/__init__.py | 0 .../parser/transactionid_file_parser.py | 2 +- .../test/completion_invoice_transactionid_test.yml | 0 .../test/completion_transactionid_test.yml | 0 .../test/invoice.yml | 0 .../test/sale.yml | 0 70 files changed, 10 insertions(+), 10 deletions(-) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/README.rst (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/__init__.py (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/__openerp__.py (93%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/data/completion_rule_data.xml (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/i18n/account_statement_bankaccount_completion.pot (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/i18n/es.po (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/i18n/fr.po (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/models/__init__.py (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/models/account_move.py (96%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/models/res_partner_bank.py (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/tests/__init__.py (100%) rename {account_statement_bankaccount_completion => account_move_bankaccount_import}/tests/test_bankaccount_completion.py (100%) rename {account_statement_base_import => account_move_base_import}/README.rst (100%) rename {account_statement_base_import => account_move_base_import}/__init__.py (100%) rename {account_statement_base_import => account_move_base_import}/__openerp__.py (100%) rename {account_statement_base_import => account_move_base_import}/data/completion_rule_data.xml (100%) rename {account_statement_base_import => account_move_base_import}/data/statement.csv (100%) rename {account_statement_base_import => account_move_base_import}/data/statement.xls (100%) rename {account_statement_base_import => account_move_base_import}/i18n/account_statement_base_import.pot (100%) rename {account_statement_base_import => account_move_base_import}/i18n/es.po (100%) rename {account_statement_base_import => account_move_base_import}/i18n/fr.po (100%) rename {account_statement_base_import => account_move_base_import}/models/__init__.py (100%) rename {account_statement_base_import => account_move_base_import}/models/account_journal.py (100%) rename {account_statement_base_import => account_move_base_import}/models/account_move.py (99%) rename {account_statement_base_import => account_move_base_import}/models/partner.py (100%) rename {account_statement_base_import => account_move_base_import}/parser/__init__.py (100%) rename {account_statement_base_import => account_move_base_import}/parser/file_parser.py (100%) rename {account_statement_base_import => account_move_base_import}/parser/generic_file_parser.py (97%) rename {account_statement_base_import => account_move_base_import}/parser/parser.py (100%) rename {account_statement_base_import => account_move_base_import}/security/ir.model.access.csv (100%) rename {account_statement_base_import => account_move_base_import}/test/completion_test.yml (100%) rename {account_statement_base_import => account_move_base_import}/test/invoice.yml (100%) rename {account_statement_base_import => account_move_base_import}/test/partner.yml (100%) rename {account_statement_base_import => account_move_base_import}/test/refund.yml (100%) rename {account_statement_base_import => account_move_base_import}/test/supplier_invoice.yml (100%) rename {account_statement_base_import => account_move_base_import}/tests/__init__.py (100%) rename {account_statement_base_import => account_move_base_import}/tests/test_base_completion.py (98%) rename {account_statement_base_import => account_move_base_import}/tests/test_base_import.py (100%) rename {account_statement_base_import => account_move_base_import}/views/account_move_view.xml (100%) rename {account_statement_base_import => account_move_base_import}/views/journal_view.xml (100%) rename {account_statement_base_import => account_move_base_import}/views/partner_view.xml (100%) rename {account_statement_base_import => account_move_base_import}/wizard/__init__.py (100%) rename {account_statement_base_import => account_move_base_import}/wizard/import_statement.py (100%) rename {account_statement_base_import => account_move_base_import}/wizard/import_statement_view.xml (100%) rename {account_statement_so_completion => account_move_so_import}/README.rst (100%) rename {account_statement_so_completion => account_move_so_import}/__init__.py (100%) rename {account_statement_so_completion => account_move_so_import}/__openerp__.py (91%) rename {account_statement_so_completion => account_move_so_import}/data/completion_rule_data.xml (100%) rename {account_statement_so_completion => account_move_so_import}/i18n/account_statement_so_completion.pot (100%) rename {account_statement_so_completion => account_move_so_import}/i18n/es.po (100%) rename {account_statement_so_completion => account_move_so_import}/models/__init__.py (100%) rename {account_statement_so_completion => account_move_so_import}/models/account_move.py (95%) rename {account_statement_so_completion => account_move_so_import}/test/completion_so_test.yml (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/README.rst (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/__init__.py (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/__openerp__.py (94%) rename {account_statement_transactionid_import => account_move_transactionid_import}/data/completion_rule_data.xml (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/data/statement.csv (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/data/statement.xls (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/i18n/account_statement_transactionid_import.pot (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/i18n/es.po (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/models/__init__.py (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/models/account_journal.py (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/models/account_move.py (97%) rename {account_statement_transactionid_import => account_move_transactionid_import}/parser/__init__.py (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/parser/transactionid_file_parser.py (97%) rename {account_statement_transactionid_import => account_move_transactionid_import}/test/completion_invoice_transactionid_test.yml (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/test/completion_transactionid_test.yml (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/test/invoice.yml (100%) rename {account_statement_transactionid_import => account_move_transactionid_import}/test/sale.yml (100%) diff --git a/account_statement_bankaccount_completion/README.rst b/account_move_bankaccount_import/README.rst similarity index 100% rename from account_statement_bankaccount_completion/README.rst rename to account_move_bankaccount_import/README.rst diff --git a/account_statement_bankaccount_completion/__init__.py b/account_move_bankaccount_import/__init__.py similarity index 100% rename from account_statement_bankaccount_completion/__init__.py rename to account_move_bankaccount_import/__init__.py diff --git a/account_statement_bankaccount_completion/__openerp__.py b/account_move_bankaccount_import/__openerp__.py similarity index 93% rename from account_statement_bankaccount_completion/__openerp__.py rename to account_move_bankaccount_import/__openerp__.py index 7ea934f5..41439e7e 100644 --- a/account_statement_bankaccount_completion/__openerp__.py +++ b/account_move_bankaccount_import/__openerp__.py @@ -9,7 +9,7 @@ 'category': 'Finance', 'complexity': 'normal', 'depends': [ - 'account_statement_base_import', + 'account_move_base_import', ], 'website': 'http://www.acsone.eu', 'data': [ diff --git a/account_statement_bankaccount_completion/data/completion_rule_data.xml b/account_move_bankaccount_import/data/completion_rule_data.xml similarity index 100% rename from account_statement_bankaccount_completion/data/completion_rule_data.xml rename to account_move_bankaccount_import/data/completion_rule_data.xml diff --git a/account_statement_bankaccount_completion/i18n/account_statement_bankaccount_completion.pot b/account_move_bankaccount_import/i18n/account_statement_bankaccount_completion.pot similarity index 100% rename from account_statement_bankaccount_completion/i18n/account_statement_bankaccount_completion.pot rename to account_move_bankaccount_import/i18n/account_statement_bankaccount_completion.pot diff --git a/account_statement_bankaccount_completion/i18n/es.po b/account_move_bankaccount_import/i18n/es.po similarity index 100% rename from account_statement_bankaccount_completion/i18n/es.po rename to account_move_bankaccount_import/i18n/es.po diff --git a/account_statement_bankaccount_completion/i18n/fr.po b/account_move_bankaccount_import/i18n/fr.po similarity index 100% rename from account_statement_bankaccount_completion/i18n/fr.po rename to account_move_bankaccount_import/i18n/fr.po diff --git a/account_statement_bankaccount_completion/models/__init__.py b/account_move_bankaccount_import/models/__init__.py similarity index 100% rename from account_statement_bankaccount_completion/models/__init__.py rename to account_move_bankaccount_import/models/__init__.py diff --git a/account_statement_bankaccount_completion/models/account_move.py b/account_move_bankaccount_import/models/account_move.py similarity index 96% rename from account_statement_bankaccount_completion/models/account_move.py rename to account_move_bankaccount_import/models/account_move.py index 5f493b1f..3ba04a36 100644 --- a/account_statement_bankaccount_completion/models/account_move.py +++ b/account_move_bankaccount_import/models/account_move.py @@ -2,7 +2,7 @@ # © 2013 ACSONE SA/NV # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from openerp import _, fields, models -from openerp.addons.account_statement_base_import.models.account_move \ +from openerp.addons.account_move_base_import.models.account_move \ import ErrorTooManyPartner diff --git a/account_statement_bankaccount_completion/models/res_partner_bank.py b/account_move_bankaccount_import/models/res_partner_bank.py similarity index 100% rename from account_statement_bankaccount_completion/models/res_partner_bank.py rename to account_move_bankaccount_import/models/res_partner_bank.py diff --git a/account_statement_bankaccount_completion/tests/__init__.py b/account_move_bankaccount_import/tests/__init__.py similarity index 100% rename from account_statement_bankaccount_completion/tests/__init__.py rename to account_move_bankaccount_import/tests/__init__.py diff --git a/account_statement_bankaccount_completion/tests/test_bankaccount_completion.py b/account_move_bankaccount_import/tests/test_bankaccount_completion.py similarity index 100% rename from account_statement_bankaccount_completion/tests/test_bankaccount_completion.py rename to account_move_bankaccount_import/tests/test_bankaccount_completion.py diff --git a/account_statement_base_import/README.rst b/account_move_base_import/README.rst similarity index 100% rename from account_statement_base_import/README.rst rename to account_move_base_import/README.rst diff --git a/account_statement_base_import/__init__.py b/account_move_base_import/__init__.py similarity index 100% rename from account_statement_base_import/__init__.py rename to account_move_base_import/__init__.py diff --git a/account_statement_base_import/__openerp__.py b/account_move_base_import/__openerp__.py similarity index 100% rename from account_statement_base_import/__openerp__.py rename to account_move_base_import/__openerp__.py diff --git a/account_statement_base_import/data/completion_rule_data.xml b/account_move_base_import/data/completion_rule_data.xml similarity index 100% rename from account_statement_base_import/data/completion_rule_data.xml rename to account_move_base_import/data/completion_rule_data.xml diff --git a/account_statement_base_import/data/statement.csv b/account_move_base_import/data/statement.csv similarity index 100% rename from account_statement_base_import/data/statement.csv rename to account_move_base_import/data/statement.csv diff --git a/account_statement_base_import/data/statement.xls b/account_move_base_import/data/statement.xls similarity index 100% rename from account_statement_base_import/data/statement.xls rename to account_move_base_import/data/statement.xls diff --git a/account_statement_base_import/i18n/account_statement_base_import.pot b/account_move_base_import/i18n/account_statement_base_import.pot similarity index 100% rename from account_statement_base_import/i18n/account_statement_base_import.pot rename to account_move_base_import/i18n/account_statement_base_import.pot diff --git a/account_statement_base_import/i18n/es.po b/account_move_base_import/i18n/es.po similarity index 100% rename from account_statement_base_import/i18n/es.po rename to account_move_base_import/i18n/es.po diff --git a/account_statement_base_import/i18n/fr.po b/account_move_base_import/i18n/fr.po similarity index 100% rename from account_statement_base_import/i18n/fr.po rename to account_move_base_import/i18n/fr.po diff --git a/account_statement_base_import/models/__init__.py b/account_move_base_import/models/__init__.py similarity index 100% rename from account_statement_base_import/models/__init__.py rename to account_move_base_import/models/__init__.py diff --git a/account_statement_base_import/models/account_journal.py b/account_move_base_import/models/account_journal.py similarity index 100% rename from account_statement_base_import/models/account_journal.py rename to account_move_base_import/models/account_journal.py diff --git a/account_statement_base_import/models/account_move.py b/account_move_base_import/models/account_move.py similarity index 99% rename from account_statement_base_import/models/account_move.py rename to account_move_base_import/models/account_move.py index f57a4270..fc9bff32 100644 --- a/account_statement_base_import/models/account_move.py +++ b/account_move_base_import/models/account_move.py @@ -236,7 +236,7 @@ class AccountMoveLine(models.Model): The idea here is to store all bank/office infos in the additionnal_bank_fields serialized field when importing the file. If many values, add a tab in the bank statement line to store your specific one. - Have a look in account_statement_base_import module to see how we've done + Have a look in account_move_base_import module to see how we've done it. """ _inherit = "account.move.line" diff --git a/account_statement_base_import/models/partner.py b/account_move_base_import/models/partner.py similarity index 100% rename from account_statement_base_import/models/partner.py rename to account_move_base_import/models/partner.py diff --git a/account_statement_base_import/parser/__init__.py b/account_move_base_import/parser/__init__.py similarity index 100% rename from account_statement_base_import/parser/__init__.py rename to account_move_base_import/parser/__init__.py diff --git a/account_statement_base_import/parser/file_parser.py b/account_move_base_import/parser/file_parser.py similarity index 100% rename from account_statement_base_import/parser/file_parser.py rename to account_move_base_import/parser/file_parser.py diff --git a/account_statement_base_import/parser/generic_file_parser.py b/account_move_base_import/parser/generic_file_parser.py similarity index 97% rename from account_statement_base_import/parser/generic_file_parser.py rename to account_move_base_import/parser/generic_file_parser.py index 9c824a4a..f2f7b5d0 100644 --- a/account_statement_base_import/parser/generic_file_parser.py +++ b/account_move_base_import/parser/generic_file_parser.py @@ -6,7 +6,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) import datetime from .file_parser import FileParser -from openerp.addons.account_statement_base_import.parser.file_parser import ( +from openerp.addons.account_move_base_import.parser.file_parser import ( float_or_zero ) from openerp.tools import ustr diff --git a/account_statement_base_import/parser/parser.py b/account_move_base_import/parser/parser.py similarity index 100% rename from account_statement_base_import/parser/parser.py rename to account_move_base_import/parser/parser.py diff --git a/account_statement_base_import/security/ir.model.access.csv b/account_move_base_import/security/ir.model.access.csv similarity index 100% rename from account_statement_base_import/security/ir.model.access.csv rename to account_move_base_import/security/ir.model.access.csv diff --git a/account_statement_base_import/test/completion_test.yml b/account_move_base_import/test/completion_test.yml similarity index 100% rename from account_statement_base_import/test/completion_test.yml rename to account_move_base_import/test/completion_test.yml diff --git a/account_statement_base_import/test/invoice.yml b/account_move_base_import/test/invoice.yml similarity index 100% rename from account_statement_base_import/test/invoice.yml rename to account_move_base_import/test/invoice.yml diff --git a/account_statement_base_import/test/partner.yml b/account_move_base_import/test/partner.yml similarity index 100% rename from account_statement_base_import/test/partner.yml rename to account_move_base_import/test/partner.yml diff --git a/account_statement_base_import/test/refund.yml b/account_move_base_import/test/refund.yml similarity index 100% rename from account_statement_base_import/test/refund.yml rename to account_move_base_import/test/refund.yml diff --git a/account_statement_base_import/test/supplier_invoice.yml b/account_move_base_import/test/supplier_invoice.yml similarity index 100% rename from account_statement_base_import/test/supplier_invoice.yml rename to account_move_base_import/test/supplier_invoice.yml diff --git a/account_statement_base_import/tests/__init__.py b/account_move_base_import/tests/__init__.py similarity index 100% rename from account_statement_base_import/tests/__init__.py rename to account_move_base_import/tests/__init__.py diff --git a/account_statement_base_import/tests/test_base_completion.py b/account_move_base_import/tests/test_base_completion.py similarity index 98% rename from account_statement_base_import/tests/test_base_completion.py rename to account_move_base_import/tests/test_base_completion.py index 28825605..8e36ee10 100644 --- a/account_statement_base_import/tests/test_base_completion.py +++ b/account_move_base_import/tests/test_base_completion.py @@ -55,7 +55,7 @@ class BaseCompletion(common.TransactionCase): the partner appears in the statement line label """ self.completion_rule_id = self.ref( - 'account_statement_base_import.bank_statement_completion_rule_3') + 'account_move_base_import.bank_statement_completion_rule_3') # Create the profile self.journal.write({ 'used_for_completion': True, diff --git a/account_statement_base_import/tests/test_base_import.py b/account_move_base_import/tests/test_base_import.py similarity index 100% rename from account_statement_base_import/tests/test_base_import.py rename to account_move_base_import/tests/test_base_import.py diff --git a/account_statement_base_import/views/account_move_view.xml b/account_move_base_import/views/account_move_view.xml similarity index 100% rename from account_statement_base_import/views/account_move_view.xml rename to account_move_base_import/views/account_move_view.xml diff --git a/account_statement_base_import/views/journal_view.xml b/account_move_base_import/views/journal_view.xml similarity index 100% rename from account_statement_base_import/views/journal_view.xml rename to account_move_base_import/views/journal_view.xml diff --git a/account_statement_base_import/views/partner_view.xml b/account_move_base_import/views/partner_view.xml similarity index 100% rename from account_statement_base_import/views/partner_view.xml rename to account_move_base_import/views/partner_view.xml diff --git a/account_statement_base_import/wizard/__init__.py b/account_move_base_import/wizard/__init__.py similarity index 100% rename from account_statement_base_import/wizard/__init__.py rename to account_move_base_import/wizard/__init__.py diff --git a/account_statement_base_import/wizard/import_statement.py b/account_move_base_import/wizard/import_statement.py similarity index 100% rename from account_statement_base_import/wizard/import_statement.py rename to account_move_base_import/wizard/import_statement.py diff --git a/account_statement_base_import/wizard/import_statement_view.xml b/account_move_base_import/wizard/import_statement_view.xml similarity index 100% rename from account_statement_base_import/wizard/import_statement_view.xml rename to account_move_base_import/wizard/import_statement_view.xml diff --git a/account_statement_so_completion/README.rst b/account_move_so_import/README.rst similarity index 100% rename from account_statement_so_completion/README.rst rename to account_move_so_import/README.rst diff --git a/account_statement_so_completion/__init__.py b/account_move_so_import/__init__.py similarity index 100% rename from account_statement_so_completion/__init__.py rename to account_move_so_import/__init__.py diff --git a/account_statement_so_completion/__openerp__.py b/account_move_so_import/__openerp__.py similarity index 91% rename from account_statement_so_completion/__openerp__.py rename to account_move_so_import/__openerp__.py index b3b83a65..55126b6b 100644 --- a/account_statement_so_completion/__openerp__.py +++ b/account_move_so_import/__openerp__.py @@ -8,7 +8,7 @@ 'maintainer': 'Camptocamp', 'category': 'Finance', 'complexity': 'easy', - 'depends': ['account_statement_base_import', 'sale'], + 'depends': ['account_move_base_import', 'sale'], 'website': 'http://www.camptocamp.com', 'data': [ 'data/completion_rule_data.xml', diff --git a/account_statement_so_completion/data/completion_rule_data.xml b/account_move_so_import/data/completion_rule_data.xml similarity index 100% rename from account_statement_so_completion/data/completion_rule_data.xml rename to account_move_so_import/data/completion_rule_data.xml diff --git a/account_statement_so_completion/i18n/account_statement_so_completion.pot b/account_move_so_import/i18n/account_statement_so_completion.pot similarity index 100% rename from account_statement_so_completion/i18n/account_statement_so_completion.pot rename to account_move_so_import/i18n/account_statement_so_completion.pot diff --git a/account_statement_so_completion/i18n/es.po b/account_move_so_import/i18n/es.po similarity index 100% rename from account_statement_so_completion/i18n/es.po rename to account_move_so_import/i18n/es.po diff --git a/account_statement_so_completion/models/__init__.py b/account_move_so_import/models/__init__.py similarity index 100% rename from account_statement_so_completion/models/__init__.py rename to account_move_so_import/models/__init__.py diff --git a/account_statement_so_completion/models/account_move.py b/account_move_so_import/models/account_move.py similarity index 95% rename from account_statement_so_completion/models/account_move.py rename to account_move_so_import/models/account_move.py index 852d4e60..c4317167 100644 --- a/account_statement_so_completion/models/account_move.py +++ b/account_move_so_import/models/account_move.py @@ -2,7 +2,7 @@ # © 2011-2016 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from openerp import _, models -from openerp.addons.account_statement_base_import.models.account_move \ +from openerp.addons.account_move_base_import.models.account_move \ import ErrorTooManyPartner diff --git a/account_statement_so_completion/test/completion_so_test.yml b/account_move_so_import/test/completion_so_test.yml similarity index 100% rename from account_statement_so_completion/test/completion_so_test.yml rename to account_move_so_import/test/completion_so_test.yml diff --git a/account_statement_transactionid_import/README.rst b/account_move_transactionid_import/README.rst similarity index 100% rename from account_statement_transactionid_import/README.rst rename to account_move_transactionid_import/README.rst diff --git a/account_statement_transactionid_import/__init__.py b/account_move_transactionid_import/__init__.py similarity index 100% rename from account_statement_transactionid_import/__init__.py rename to account_move_transactionid_import/__init__.py diff --git a/account_statement_transactionid_import/__openerp__.py b/account_move_transactionid_import/__openerp__.py similarity index 94% rename from account_statement_transactionid_import/__openerp__.py rename to account_move_transactionid_import/__openerp__.py index bfbc086e..869581e8 100644 --- a/account_statement_transactionid_import/__openerp__.py +++ b/account_move_transactionid_import/__openerp__.py @@ -9,7 +9,7 @@ 'category': 'Finance', 'complexity': 'normal', 'depends': [ - 'account_statement_base_import', + 'account_move_base_import', 'base_transaction_id' ], 'data': [ diff --git a/account_statement_transactionid_import/data/completion_rule_data.xml b/account_move_transactionid_import/data/completion_rule_data.xml similarity index 100% rename from account_statement_transactionid_import/data/completion_rule_data.xml rename to account_move_transactionid_import/data/completion_rule_data.xml diff --git a/account_statement_transactionid_import/data/statement.csv b/account_move_transactionid_import/data/statement.csv similarity index 100% rename from account_statement_transactionid_import/data/statement.csv rename to account_move_transactionid_import/data/statement.csv diff --git a/account_statement_transactionid_import/data/statement.xls b/account_move_transactionid_import/data/statement.xls similarity index 100% rename from account_statement_transactionid_import/data/statement.xls rename to account_move_transactionid_import/data/statement.xls diff --git a/account_statement_transactionid_import/i18n/account_statement_transactionid_import.pot b/account_move_transactionid_import/i18n/account_statement_transactionid_import.pot similarity index 100% rename from account_statement_transactionid_import/i18n/account_statement_transactionid_import.pot rename to account_move_transactionid_import/i18n/account_statement_transactionid_import.pot diff --git a/account_statement_transactionid_import/i18n/es.po b/account_move_transactionid_import/i18n/es.po similarity index 100% rename from account_statement_transactionid_import/i18n/es.po rename to account_move_transactionid_import/i18n/es.po diff --git a/account_statement_transactionid_import/models/__init__.py b/account_move_transactionid_import/models/__init__.py similarity index 100% rename from account_statement_transactionid_import/models/__init__.py rename to account_move_transactionid_import/models/__init__.py diff --git a/account_statement_transactionid_import/models/account_journal.py b/account_move_transactionid_import/models/account_journal.py similarity index 100% rename from account_statement_transactionid_import/models/account_journal.py rename to account_move_transactionid_import/models/account_journal.py diff --git a/account_statement_transactionid_import/models/account_move.py b/account_move_transactionid_import/models/account_move.py similarity index 97% rename from account_statement_transactionid_import/models/account_move.py rename to account_move_transactionid_import/models/account_move.py index ded1bcd1..e2a31bb9 100644 --- a/account_statement_transactionid_import/models/account_move.py +++ b/account_move_transactionid_import/models/account_move.py @@ -2,7 +2,7 @@ # © 2011-2016 Camptocamp SA # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) from openerp import _, models -from openerp.addons.account_statement_base_import.models.account_move import \ +from openerp.addons.account_move_base_import.models.account_move import \ ErrorTooManyPartner diff --git a/account_statement_transactionid_import/parser/__init__.py b/account_move_transactionid_import/parser/__init__.py similarity index 100% rename from account_statement_transactionid_import/parser/__init__.py rename to account_move_transactionid_import/parser/__init__.py diff --git a/account_statement_transactionid_import/parser/transactionid_file_parser.py b/account_move_transactionid_import/parser/transactionid_file_parser.py similarity index 97% rename from account_statement_transactionid_import/parser/transactionid_file_parser.py rename to account_move_transactionid_import/parser/transactionid_file_parser.py index 1150d6ec..a11501c3 100644 --- a/account_statement_transactionid_import/parser/transactionid_file_parser.py +++ b/account_move_transactionid_import/parser/transactionid_file_parser.py @@ -3,7 +3,7 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html) import datetime from openerp.tools import ustr -from openerp.addons.account_statement_base_import.parser.file_parser import ( +from openerp.addons.account_move_base_import.parser.file_parser import ( FileParser, float_or_zero ) diff --git a/account_statement_transactionid_import/test/completion_invoice_transactionid_test.yml b/account_move_transactionid_import/test/completion_invoice_transactionid_test.yml similarity index 100% rename from account_statement_transactionid_import/test/completion_invoice_transactionid_test.yml rename to account_move_transactionid_import/test/completion_invoice_transactionid_test.yml diff --git a/account_statement_transactionid_import/test/completion_transactionid_test.yml b/account_move_transactionid_import/test/completion_transactionid_test.yml similarity index 100% rename from account_statement_transactionid_import/test/completion_transactionid_test.yml rename to account_move_transactionid_import/test/completion_transactionid_test.yml diff --git a/account_statement_transactionid_import/test/invoice.yml b/account_move_transactionid_import/test/invoice.yml similarity index 100% rename from account_statement_transactionid_import/test/invoice.yml rename to account_move_transactionid_import/test/invoice.yml diff --git a/account_statement_transactionid_import/test/sale.yml b/account_move_transactionid_import/test/sale.yml similarity index 100% rename from account_statement_transactionid_import/test/sale.yml rename to account_move_transactionid_import/test/sale.yml From 43f8bbf1563a301a4265b42b6025899ccfed3104 Mon Sep 17 00:00:00 2001 From: Matthieu Dietrich Date: Tue, 24 May 2016 13:47:33 +0200 Subject: [PATCH 20/32] Rename last values --- account_move_bankaccount_import/i18n/es.po | 16 +- account_move_bankaccount_import/i18n/fr.po | 16 +- .../models/account_move.py | 10 +- .../tests/test_bankaccount_completion.py | 2 +- account_move_base_import/i18n/es.po | 158 +++++++++--------- account_move_base_import/i18n/fr.po | 158 +++++++++--------- .../models/account_journal.py | 10 +- .../models/account_move.py | 32 ++-- .../views/journal_view.xml | 2 +- account_move_so_import/i18n/es.po | 8 +- account_move_so_import/models/account_move.py | 10 +- .../test/completion_so_test.yml | 8 +- account_move_transactionid_import/i18n/es.po | 8 +- .../models/account_journal.py | 13 +- .../models/account_move.py | 12 +- .../test/completion_transactionid_test.yml | 8 +- 16 files changed, 223 insertions(+), 248 deletions(-) diff --git a/account_move_bankaccount_import/i18n/es.po b/account_move_bankaccount_import/i18n/es.po index c42aa57c..d3d2ceb6 100644 --- a/account_move_bankaccount_import/i18n/es.po +++ b/account_move_bankaccount_import/i18n/es.po @@ -17,18 +17,18 @@ msgstr "" "X-Launchpad-Export-Date: 2014-06-06 06:36+0000\n" "X-Generator: Launchpad (build 17031)\n" -#. module: account_statement_bankaccount_completion +#. module: account_move_bankaccount_import #: help:account.bank.statement.line,partner_acc_number:0 msgid "Account number of the partner" msgstr "Número de cuenta de la empresa" -#. module: account_statement_bankaccount_completion -#: model:ir.model,name:account_statement_bankaccount_completion.model_account_bank_statement_line +#. module: account_move_bankaccount_import +#: model:ir.model,name:account_move_bankaccount_import.model_account_bank_statement_line msgid "Bank Statement Line" msgstr "Línea de extracto bancario" -#. module: account_statement_bankaccount_completion -#: code:addons/account_statement_bankaccount_completion/statement.py:68 +#. module: account_move_bankaccount_import +#: code:addons/account_move_bankaccount_import/statement.py:68 #, python-format msgid "" "Line named \"%s\" (Ref:%s) was matched by more than one partner for account " @@ -37,12 +37,12 @@ msgstr "" "La línea llamada \"%s\" (Ref: %s) fue casada con más de una empresa al " "buscar el nº de cuenta \"%s\"." -#. module: account_statement_bankaccount_completion +#. module: account_move_bankaccount_import #: field:account.bank.statement.line,partner_acc_number:0 msgid "Account Number" msgstr "Número de cuenta" -#. module: account_statement_bankaccount_completion -#: model:ir.model,name:account_statement_bankaccount_completion.model_account_statement_completion_rule +#. module: account_move_bankaccount_import +#: model:ir.model,name:account_move_bankaccount_import.model_account_statement_completion_rule msgid "account.statement.completion.rule" msgstr "account.statement.completion.rule" diff --git a/account_move_bankaccount_import/i18n/fr.po b/account_move_bankaccount_import/i18n/fr.po index d084efae..7e1e31b4 100644 --- a/account_move_bankaccount_import/i18n/fr.po +++ b/account_move_bankaccount_import/i18n/fr.po @@ -17,30 +17,30 @@ msgstr "" "X-Launchpad-Export-Date: 2014-06-20 06:09+0000\n" "X-Generator: Launchpad (build 17058)\n" -#. module: account_statement_bankaccount_completion +#. module: account_move_bankaccount_import #: help:account.bank.statement.line,partner_acc_number:0 msgid "Account number of the partner" msgstr "" -#. module: account_statement_bankaccount_completion -#: model:ir.model,name:account_statement_bankaccount_completion.model_account_bank_statement_line +#. module: account_move_bankaccount_import +#: model:ir.model,name:account_move_bankaccount_import.model_account_bank_statement_line msgid "Bank Statement Line" msgstr "Ligne de relevé bancaire" -#. module: account_statement_bankaccount_completion -#: code:addons/account_statement_bankaccount_completion/statement.py:68 +#. module: account_move_bankaccount_import +#: code:addons/account_move_bankaccount_import/statement.py:68 #, python-format msgid "" "Line named \"%s\" (Ref:%s) was matched by more than one partner for account " "number \"%s\"." msgstr "" -#. module: account_statement_bankaccount_completion +#. module: account_move_bankaccount_import #: field:account.bank.statement.line,partner_acc_number:0 msgid "Account Number" msgstr "Numéro de compte" -#. module: account_statement_bankaccount_completion -#: model:ir.model,name:account_statement_bankaccount_completion.model_account_statement_completion_rule +#. module: account_move_bankaccount_import +#: model:ir.model,name:account_move_bankaccount_import.model_account_statement_completion_rule msgid "account.statement.completion.rule" msgstr "" diff --git a/account_move_bankaccount_import/models/account_move.py b/account_move_bankaccount_import/models/account_move.py index 3ba04a36..ed882422 100644 --- a/account_move_bankaccount_import/models/account_move.py +++ b/account_move_bankaccount_import/models/account_move.py @@ -11,11 +11,11 @@ class AccountMoveCompletionRule(models.Model): _inherit = "account.move.completion.rule" - def _get_functions(self): - res = super(AccountMoveCompletionRule, self)._get_functions() - res.append(('get_from_bank_account', - 'From bank account number (Normal or IBAN)')) - return res + function_to_call = fields.Selection( + selection_add=[ + ('get_from_bank_account', + 'From bank account number (Normal or IBAN)') + ]) def get_from_bank_account(self, line): """ diff --git a/account_move_bankaccount_import/tests/test_bankaccount_completion.py b/account_move_bankaccount_import/tests/test_bankaccount_completion.py index d0b37369..d641f938 100644 --- a/account_move_bankaccount_import/tests/test_bankaccount_completion.py +++ b/account_move_bankaccount_import/tests/test_bankaccount_completion.py @@ -23,7 +23,7 @@ class BankAccountCompletion(common.TransactionCase): ) self.company_a = self.browse_ref('base.main_company') self.completion_rule_id = \ - self.ref('account_statement_bankaccount_completion.' + self.ref('account_move_bankaccount_import.' 'bank_statement_completion_rule_10') self.journal = self.browse_ref("account.bank_journal") self.partner = self.browse_ref('base.main_partner') diff --git a/account_move_base_import/i18n/es.po b/account_move_base_import/i18n/es.po index b990338f..41dc3b2b 100644 --- a/account_move_base_import/i18n/es.po +++ b/account_move_base_import/i18n/es.po @@ -17,29 +17,29 @@ msgstr "" "X-Launchpad-Export-Date: 2014-06-06 06:36+0000\n" "X-Generator: Launchpad (build 17031)\n" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:credit.statement.import:0 -#: model:ir.actions.act_window,name:account_statement_base_import.statement_importer_action +#: model:ir.actions.act_window,name:account_move_base_import.statement_importer_action msgid "Import statement" msgstr "Importar extracto" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:account.statement.profile:0 msgid "Historical Import Logs" msgstr "Registro histórico de importaciones" -#. module: account_statement_base_import -#: model:ir.model,name:account_statement_base_import.model_credit_statement_import +#. module: account_move_base_import +#: model:ir.model,name:account_move_base_import.model_credit_statement_import msgid "credit.statement.import" msgstr "credit.statement.import" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,input_statement:0 msgid "Statement file" msgstr "Archivo de extracto" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:168 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:168 #, python-format msgid "" "Column %s you try to import is not present in the bank statement line!" @@ -47,91 +47,91 @@ msgstr "" "La columna %s que intenta importar no está presente en la línea del extracto " "bancario." -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:162 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:162 #, python-format msgid "Nothing to import" msgstr "Nada que importar" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,journal_id:0 msgid "Financial journal to use transaction" msgstr "Diario contable a usar" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:102 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:102 #, python-format msgid "Column %s not present in file" msgstr "La columna %s no está presente en el archivo" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:account.statement.profile:0 -#: model:ir.ui.menu,name:account_statement_base_import.statement_importer_menu +#: model:ir.ui.menu,name:account_move_base_import.statement_importer_menu msgid "Import Bank Statement" msgstr "Importar extracto bancario" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:54 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:54 #, python-format msgid "User Error" msgstr "Error de usuario" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:223 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:223 #, python-format msgid "The statement cannot be created: %s" msgstr "El extracto no puede ser creado: %s" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:167 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:167 #, python-format msgid "Missing column!" msgstr "Columna ausente" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/parser.py:166 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/parser.py:166 #, python-format msgid "No buffer file given." msgstr "No se ha proporcionado ningún búfer de archivo." -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:107 -#: code:addons/account_statement_base_import/parser/file_parser.py:171 -#: code:addons/account_statement_base_import/parser/file_parser.py:205 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:107 +#: code:addons/account_move_base_import/parser/file_parser.py:171 +#: code:addons/account_move_base_import/parser/file_parser.py:205 #, python-format msgid "Invalid data" msgstr "Datos inválidos" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:account.statement.profile,launch_import_completion:0 msgid "Launch completion after import" msgstr "Lanzar el completado después de la importación" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,partner_id:0 msgid "Credit insitute partner" msgstr "Empresa para el agente financiero" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:account.statement.profile:0 msgid "Import related infos" msgstr "Importar información relacionada" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:163 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:163 #, python-format msgid "The file is empty" msgstr "El archivo está vacío" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/wizard/import_statement.py:93 +#. module: account_move_base_import +#: code:addons/account_move_base_import/wizard/import_statement.py:93 #, python-format msgid "Please use a file with an extention" msgstr "Use por favor un archivo con extensión" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:172 -#: code:addons/account_statement_base_import/parser/file_parser.py:206 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:172 +#: code:addons/account_move_base_import/parser/file_parser.py:206 #, python-format msgid "" "Value %s of column %s is not valid.\n" @@ -145,15 +145,15 @@ msgstr "" " \n" "Detalles: %s" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:29 -#: code:addons/account_statement_base_import/parser/generic_file_parser.py:31 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:29 +#: code:addons/account_move_base_import/parser/generic_file_parser.py:31 #, python-format msgid "Please install python lib xlrd" msgstr "Por favor instale la librería de Python xlrd" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:160 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:160 #, python-format msgid "" " It should be YYYY-MM-DD for column: %s value: %s \n" @@ -169,24 +169,24 @@ msgstr "" " \n" "Detalles: %s" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:account.statement.profile,last_import_date:0 msgid "Last Import Date" msgstr "Última fecha de importación" -#. module: account_statement_base_import -#: model:ir.model,name:account_statement_base_import.model_account_statement_profile +#. module: account_move_base_import +#: model:ir.model,name:account_move_base_import.model_account_statement_profile msgid "Statement Profile" msgstr "Perfil de extracto" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:234 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:234 #, python-format msgid "Statement import error" msgstr "Error de importación del extracto" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:193 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:193 #, python-format msgid "" "Please modify the cell formatting to date format for column: %s value: %s\n" @@ -200,18 +200,18 @@ msgstr "" " \n" "Detalles: %s" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:192 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:192 #, python-format msgid "Date format is not valid" msgstr "El formato de fecha no es válido" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:account.statement.profile,import_type:0 msgid "Type of import" msgstr "Tipo de importación" -#. module: account_statement_base_import +#. module: account_move_base_import #: help:account.statement.profile,launch_import_completion:0 msgid "" "Tic that box to automatically launch the completion on each imported file " @@ -220,7 +220,7 @@ msgstr "" "Marque esta casilla para lanzar automáticamente el completado en cada " "archivo importado usando este perfil." -#. module: account_statement_base_import +#. module: account_move_base_import #: help:credit.statement.import,balance_check:0 msgid "" "Tic that box if you want OpenERP to control the start/end balance before " @@ -231,81 +231,81 @@ msgstr "" "antes de confirmar un extracto bancaria. Si no está marcada, no se realizará " "ningún control de saldo." -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:154 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:154 #, python-format msgid "No Profile!" msgstr "Sin perfil" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:159 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:159 #, python-format msgid "Date format is not valid." msgstr "El formato de fecha no es válido." -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,profile_id:0 msgid "Import configuration parameter" msgstr "Parámetros de configuración de la importación" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:account.statement.profile,rec_log:0 msgid "log" msgstr "registro" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:credit.statement.import:0 msgid "Import Parameters Summary" msgstr "Resumen de parámetros de importación" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,balance_check:0 msgid "Balance check" msgstr "Comprobar saldo" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,force_partner_on_bank:0 msgid "Force partner on bank move" msgstr "Forzar empresa en el apunte bancario" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,file_name:0 msgid "File Name" msgstr "Nombre del archivo" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:55 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:55 #, python-format msgid "Invalid file type %s. Please use csv or xls" msgstr "Tipo de archivo %s no válido. Utilice por favor CSV o XLS." -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:155 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:155 #, python-format msgid "You must provide a valid profile to import a bank statement!" msgstr "Debe introducir un perfil válido para importar un extracto bancario" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:83 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:83 #, python-format msgid "Statement ID %s have been imported with %s lines." msgstr "El extracto con ID %s ha sido importado con %s líneas." -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,receivable_account_id:0 msgid "Force Receivable/Payable Account" msgstr "Forzar cuenta a cobrar/a pagar" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:164 -#: code:addons/account_statement_base_import/parser/file_parser.py:174 -#: code:addons/account_statement_base_import/parser/file_parser.py:198 -#: code:addons/account_statement_base_import/parser/file_parser.py:208 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:164 +#: code:addons/account_move_base_import/parser/file_parser.py:174 +#: code:addons/account_move_base_import/parser/file_parser.py:198 +#: code:addons/account_move_base_import/parser/file_parser.py:208 #, python-format msgid "Missing" msgstr "Ausente" -#. module: account_statement_base_import +#. module: account_move_base_import #: help:account.statement.profile,import_type:0 msgid "" "Choose here the method by which you want to import bank statement for this " @@ -314,12 +314,12 @@ msgstr "" "Escoja aquí el método con el que quiere importar el extracto bancario para " "este perfil." -#. module: account_statement_base_import +#. module: account_move_base_import #: view:credit.statement.import:0 msgid "Cancel" msgstr "Cancelar" -#. module: account_statement_base_import +#. module: account_move_base_import #: help:credit.statement.import,force_partner_on_bank:0 msgid "" "Tic that box if you want to use the credit insitute partner in the " diff --git a/account_move_base_import/i18n/fr.po b/account_move_base_import/i18n/fr.po index a1418535..15407a9f 100644 --- a/account_move_base_import/i18n/fr.po +++ b/account_move_base_import/i18n/fr.po @@ -17,119 +17,119 @@ msgstr "" "X-Launchpad-Export-Date: 2014-05-22 06:49+0000\n" "X-Generator: Launchpad (build 17017)\n" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:credit.statement.import:0 -#: model:ir.actions.act_window,name:account_statement_base_import.statement_importer_action +#: model:ir.actions.act_window,name:account_move_base_import.statement_importer_action msgid "Import statement" msgstr "Import de relevé" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:account.statement.profile:0 msgid "Historical Import Logs" msgstr "" -#. module: account_statement_base_import -#: model:ir.model,name:account_statement_base_import.model_credit_statement_import +#. module: account_move_base_import +#: model:ir.model,name:account_move_base_import.model_credit_statement_import msgid "credit.statement.import" msgstr "credit.statement.import" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,input_statement:0 msgid "Statement file" msgstr "Fichier à importer" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:168 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:168 #, python-format msgid "" "Column %s you try to import is not present in the bank statement line!" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:162 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:162 #, python-format msgid "Nothing to import" msgstr "" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,journal_id:0 msgid "Financial journal to use transaction" msgstr "Journal" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:102 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:102 #, python-format msgid "Column %s not present in file" msgstr "Colonne %s non présente dans le fichier" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:account.statement.profile:0 -#: model:ir.ui.menu,name:account_statement_base_import.statement_importer_menu +#: model:ir.ui.menu,name:account_move_base_import.statement_importer_menu msgid "Import Bank Statement" msgstr "Importation de relevé" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:54 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:54 #, python-format msgid "User Error" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:223 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:223 #, python-format msgid "The statement cannot be created: %s" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:167 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:167 #, python-format msgid "Missing column!" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/parser.py:166 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/parser.py:166 #, python-format msgid "No buffer file given." msgstr "Pas de fichier tampon donné." -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:107 -#: code:addons/account_statement_base_import/parser/file_parser.py:171 -#: code:addons/account_statement_base_import/parser/file_parser.py:205 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:107 +#: code:addons/account_move_base_import/parser/file_parser.py:171 +#: code:addons/account_move_base_import/parser/file_parser.py:205 #, python-format msgid "Invalid data" msgstr "" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:account.statement.profile,launch_import_completion:0 msgid "Launch completion after import" msgstr "Lancer l'auto-complétion après import" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,partner_id:0 msgid "Credit insitute partner" msgstr "Organisme bancaire" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:account.statement.profile:0 msgid "Import related infos" msgstr "Importation des informations liées" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:163 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:163 #, python-format msgid "The file is empty" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/wizard/import_statement.py:93 +#. module: account_move_base_import +#: code:addons/account_move_base_import/wizard/import_statement.py:93 #, python-format msgid "Please use a file with an extention" msgstr "Veuillez sélectionner un fichier avec une extension" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:172 -#: code:addons/account_statement_base_import/parser/file_parser.py:206 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:172 +#: code:addons/account_move_base_import/parser/file_parser.py:206 #, python-format msgid "" "Value %s of column %s is not valid.\n" @@ -138,15 +138,15 @@ msgid "" " Detail: %s" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:29 -#: code:addons/account_statement_base_import/parser/generic_file_parser.py:31 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:29 +#: code:addons/account_move_base_import/parser/generic_file_parser.py:31 #, python-format msgid "Please install python lib xlrd" msgstr "Veuillez installer la bibliothèque python xlrd" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:160 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:160 #, python-format msgid "" " It should be YYYY-MM-DD for column: %s value: %s \n" @@ -157,24 +157,24 @@ msgid "" " Detail: %s" msgstr "" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:account.statement.profile,last_import_date:0 msgid "Last Import Date" msgstr "Date de dernier import" -#. module: account_statement_base_import -#: model:ir.model,name:account_statement_base_import.model_account_statement_profile +#. module: account_move_base_import +#: model:ir.model,name:account_move_base_import.model_account_statement_profile msgid "Statement Profile" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:234 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:234 #, python-format msgid "Statement import error" msgstr "Erreur d'import de relevé" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:193 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:193 #, python-format msgid "" "Please modify the cell formatting to date format for column: %s value: %s\n" @@ -183,25 +183,25 @@ msgid "" " Detail: %s" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:192 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:192 #, python-format msgid "Date format is not valid" msgstr "" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:account.statement.profile,import_type:0 msgid "Type of import" msgstr "Type d'import" -#. module: account_statement_base_import +#. module: account_move_base_import #: help:account.statement.profile,launch_import_completion:0 msgid "" "Tic that box to automatically launch the completion on each imported file " "using this profile." msgstr "" -#. module: account_statement_base_import +#. module: account_move_base_import #: help:credit.statement.import,balance_check:0 msgid "" "Tic that box if you want OpenERP to control the start/end balance before " @@ -209,93 +209,93 @@ msgid "" "done." msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:154 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:154 #, python-format msgid "No Profile!" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:159 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:159 #, python-format msgid "Date format is not valid." msgstr "" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,profile_id:0 msgid "Import configuration parameter" msgstr "Paramètres de configuration d'import" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:account.statement.profile,rec_log:0 msgid "log" msgstr "journal" -#. module: account_statement_base_import +#. module: account_move_base_import #: view:credit.statement.import:0 msgid "Import Parameters Summary" msgstr "Résumé des paramètres d'import" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,balance_check:0 msgid "Balance check" msgstr "Vérification des soldes" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,force_partner_on_bank:0 msgid "Force partner on bank move" msgstr "Forcer un partenaire sur la ligne du compte de banque" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,file_name:0 msgid "File Name" msgstr "Nom du fichier" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:55 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:55 #, python-format msgid "Invalid file type %s. Please use csv or xls" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:155 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:155 #, python-format msgid "You must provide a valid profile to import a bank statement!" msgstr "" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/statement.py:83 +#. module: account_move_base_import +#: code:addons/account_move_base_import/statement.py:83 #, python-format msgid "Statement ID %s have been imported with %s lines." msgstr "" -#. module: account_statement_base_import +#. module: account_move_base_import #: field:credit.statement.import,receivable_account_id:0 msgid "Force Receivable/Payable Account" msgstr "Forcer le compte Client/Fournisseur" -#. module: account_statement_base_import -#: code:addons/account_statement_base_import/parser/file_parser.py:164 -#: code:addons/account_statement_base_import/parser/file_parser.py:174 -#: code:addons/account_statement_base_import/parser/file_parser.py:198 -#: code:addons/account_statement_base_import/parser/file_parser.py:208 +#. module: account_move_base_import +#: code:addons/account_move_base_import/parser/file_parser.py:164 +#: code:addons/account_move_base_import/parser/file_parser.py:174 +#: code:addons/account_move_base_import/parser/file_parser.py:198 +#: code:addons/account_move_base_import/parser/file_parser.py:208 #, python-format msgid "Missing" msgstr "" -#. module: account_statement_base_import +#. module: account_move_base_import #: help:account.statement.profile,import_type:0 msgid "" "Choose here the method by which you want to import bank statement for this " "profile." msgstr "Choisissez la méthode d'import de relevé pour ce profil." -#. module: account_statement_base_import +#. module: account_move_base_import #: view:credit.statement.import:0 msgid "Cancel" msgstr "Annulation" -#. module: account_statement_base_import +#. module: account_move_base_import #: help:credit.statement.import,force_partner_on_bank:0 msgid "" "Tic that box if you want to use the credit insitute partner in the " diff --git a/account_move_base_import/models/account_journal.py b/account_move_base_import/models/account_journal.py index b703a798..d5fbbbe6 100644 --- a/account_move_base_import/models/account_journal.py +++ b/account_move_base_import/models/account_journal.py @@ -17,14 +17,6 @@ class AccountJournal(models.Model): _name = 'account.journal' _inherit = ['account.journal', 'mail.thread'] - def _get_import_type_selection(self): - """This is the method to be inherited for adding the parser""" - return [('generic_csvxls_so', 'Generic .csv/.xls based on SO Name')] - - def __get_import_type_selection(self): - """ Call method which can be inherited """ - return self._get_import_type_selection() - used_for_import = fields.Boolean( string="Journal used for import") @@ -33,7 +25,7 @@ class AccountJournal(models.Model): string='Commission account') import_type = fields.Selection( - __get_import_type_selection, + [('generic_csvxls_so', 'Generic .csv/.xls based on SO Name')], string='Type of import', default='generic_csvxls_so', required=True, diff --git a/account_move_base_import/models/account_move.py b/account_move_base_import/models/account_move.py index fc9bff32..b5a4a9cf 100644 --- a/account_move_base_import/models/account_move.py +++ b/account_move_base_import/models/account_move.py @@ -44,25 +44,6 @@ class AccountMoveCompletionRule(models.Model): _name = "account.move.completion.rule" _order = "sequence asc" - def _get_functions(self): - """List of available methods for rules. - - Override this to add you own.""" - return [ - ('get_from_name_and_invoice', - 'From line name (based on customer invoice number)'), - ('get_from_name_and_supplier_invoice', - 'From line name (based on supplier invoice number)'), - ('get_from_name_and_partner_field', - 'From line name (based on partner field)'), - ('get_from_name_and_partner_name', - 'From line name (based on partner name)') - ] - - def __get_functions(self): - """ Call method which can be inherited """ - return self._get_functions() - sequence = fields.Integer( string='Sequence', help="Lower means parsed first.") @@ -72,9 +53,16 @@ class AccountMoveCompletionRule(models.Model): comodel_name='account.journal', rel='as_rul_st_prof_rel', string='Related journals') - function_to_call = fields.Selection( - __get_functions, - string='Method') + function_to_call = fields.Selection([ + ('get_from_name_and_invoice', + 'From line name (based on customer invoice number)'), + ('get_from_name_and_supplier_invoice', + 'From line name (based on supplier invoice number)'), + ('get_from_name_and_partner_field', + 'From line name (based on partner field)'), + ('get_from_name_and_partner_name', + 'From line name (based on partner name)') + ], string='Method') def _find_invoice(self, line, inv_type): """Find invoice related to statement line""" diff --git a/account_move_base_import/views/journal_view.xml b/account_move_base_import/views/journal_view.xml index d3696218..37d17106 100644 --- a/account_move_base_import/views/journal_view.xml +++ b/account_move_base_import/views/journal_view.xml @@ -24,7 +24,7 @@
-