diff --git a/account_advanced_reconcile/i18n/fr.po b/account_advanced_reconcile/i18n/fr.po index 03e36753..13f55fae 100644 --- a/account_advanced_reconcile/i18n/fr.po +++ b/account_advanced_reconcile/i18n/fr.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-03 06:52+0000\n" -"X-Generator: Launchpad (build 16985)\n" +"X-Launchpad-Export-Date: 2014-05-13 06:34+0000\n" +"X-Generator: Launchpad (build 17002)\n" "Language: \n" #. module: account_advanced_reconcile diff --git a/account_advanced_reconcile_transaction_ref/i18n/fr.po b/account_advanced_reconcile_transaction_ref/i18n/fr.po index 6d9a0539..f21aca5c 100644 --- a/account_advanced_reconcile_transaction_ref/i18n/fr.po +++ b/account_advanced_reconcile_transaction_ref/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-03 06:52+0000\n" -"X-Generator: Launchpad (build 16985)\n" +"X-Launchpad-Export-Date: 2014-05-13 06:34+0000\n" +"X-Generator: Launchpad (build 17002)\n" #. module: account_advanced_reconcile_transaction_ref #: field:easy.reconcile.advanced.transaction_ref,partner_ids:0 diff --git a/account_easy_reconcile/i18n/es.po b/account_easy_reconcile/i18n/es.po index cbbc602f..348aa677 100644 --- a/account_easy_reconcile/i18n/es.po +++ b/account_easy_reconcile/i18n/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-03 06:52+0000\n" -"X-Generator: Launchpad (build 16985)\n" +"X-Launchpad-Export-Date: 2014-05-13 06:34+0000\n" +"X-Generator: Launchpad (build 17002)\n" #. module: account_easy_reconcile #: code:addons/account_easy_reconcile/easy_reconcile_history.py:101 diff --git a/account_easy_reconcile/i18n/fr.po b/account_easy_reconcile/i18n/fr.po index 1568f157..362f738e 100644 --- a/account_easy_reconcile/i18n/fr.po +++ b/account_easy_reconcile/i18n/fr.po @@ -13,8 +13,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-03 06:52+0000\n" -"X-Generator: Launchpad (build 16985)\n" +"X-Launchpad-Export-Date: 2014-05-13 06:34+0000\n" +"X-Generator: Launchpad (build 17002)\n" "Language: \n" #. module: account_easy_reconcile diff --git a/account_statement_base_completion/__openerp__.py b/account_statement_base_completion/__openerp__.py index 1b016369..feb0cb35 100644 --- a/account_statement_base_completion/__openerp__.py +++ b/account_statement_base_completion/__openerp__.py @@ -20,7 +20,7 @@ ############################################################################## {'name': "Bank statement base completion", - 'version': '1.0.2', + 'version': '1.0.3', 'author': 'Camptocamp', 'maintainer': 'Camptocamp', 'category': 'Finance', diff --git a/account_statement_base_completion/i18n/ab.po b/account_statement_base_completion/i18n/ab.po index bbada1c3..430dbc93 100644 --- a/account_statement_base_completion/i18n/ab.po +++ b/account_statement_base_completion/i18n/ab.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-03 06:52+0000\n" -"X-Generator: Launchpad (build 16985)\n" +"X-Launchpad-Export-Date: 2014-05-13 06:34+0000\n" +"X-Generator: Launchpad (build 17002)\n" #. module: account_statement_base_completion #: view:account.statement.completion.rule:0 diff --git a/account_statement_base_completion/i18n/fr.po b/account_statement_base_completion/i18n/fr.po index 22e4a1b2..4b021476 100644 --- a/account_statement_base_completion/i18n/fr.po +++ b/account_statement_base_completion/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-03 06:52+0000\n" -"X-Generator: Launchpad (build 16985)\n" +"X-Launchpad-Export-Date: 2014-05-13 06:34+0000\n" +"X-Generator: Launchpad (build 17002)\n" #. module: account_statement_base_completion #: view:account.statement.completion.rule:0 diff --git a/account_statement_base_completion/partner.py b/account_statement_base_completion/partner.py index 89c810d5..4d3a452e 100644 --- a/account_statement_base_completion/partner.py +++ b/account_statement_base_completion/partner.py @@ -20,7 +20,7 @@ ################################################################################# from openerp.osv.orm import Model -from openerp.osv import fields, osv +from openerp.osv import fields class res_partner(Model): @@ -32,7 +32,7 @@ class res_partner(Model): _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)."), + 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_completion/statement.py b/account_statement_base_completion/statement.py index 8217e917..ce478a2b 100644 --- a/account_statement_base_completion/statement.py +++ b/account_statement_base_completion/statement.py @@ -24,16 +24,17 @@ import sys import logging import simplejson import inspect +import datetime import psycopg2 from collections import defaultdict import re -from tools.translate import _ +from openerp.tools.translate import _ from openerp.osv import osv, orm, fields from openerp.tools import DEFAULT_SERVER_DATETIME_FORMAT from operator import attrgetter -import datetime + _logger = logging.getLogger(__name__) @@ -256,7 +257,7 @@ class AccountStatementCompletionRule(orm.Model): 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 + #  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 @@ -397,6 +398,8 @@ class AccountStatementLine(orm.Model): "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 = { @@ -440,6 +443,25 @@ class AccountStatementLine(orm.Model): 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 @@ -469,6 +491,7 @@ class AccountStatementLine(orm.Model): 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: @@ -487,6 +510,7 @@ class AccountStatementLine(orm.Model): 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: @@ -582,7 +606,7 @@ class AccountBankStatement(orm.Model): st += ''.join(traceback.format_tb(trbk, 30)) _logger.error(st) if res: - #stat_line_obj.write(cr, uid, [line.id], vals, context=ctx) + # 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: diff --git a/account_statement_base_import/i18n/es.po b/account_statement_base_import/i18n/es.po index 399839e3..a9114e60 100644 --- a/account_statement_base_import/i18n/es.po +++ b/account_statement_base_import/i18n/es.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-03 06:52+0000\n" -"X-Generator: Launchpad (build 16985)\n" +"X-Launchpad-Export-Date: 2014-05-13 06:34+0000\n" +"X-Generator: Launchpad (build 17002)\n" #. module: account_statement_base_import #: view:credit.statement.import:0 diff --git a/account_statement_base_import/i18n/fr.po b/account_statement_base_import/i18n/fr.po index 54c3f447..7181ad29 100644 --- a/account_statement_base_import/i18n/fr.po +++ b/account_statement_base_import/i18n/fr.po @@ -14,8 +14,8 @@ msgstr "" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2014-05-03 06:52+0000\n" -"X-Generator: Launchpad (build 16985)\n" +"X-Launchpad-Export-Date: 2014-05-13 06:34+0000\n" +"X-Generator: Launchpad (build 17002)\n" #. module: account_statement_base_import #: view:credit.statement.import:0 diff --git a/account_statement_base_import/statement.py b/account_statement_base_import/statement.py index cf07d71a..1739e65d 100644 --- a/account_statement_base_import/statement.py +++ b/account_statement_base_import/statement.py @@ -95,7 +95,7 @@ class AccountStatementProfil(Model): return self.prepare_statement_lines_vals(*args, **kwargs) def prepare_statement_lines_vals( - self, cr, uid, parser_vals, account_payable, account_receivable, + self, cr, uid, parser_vals, statement_id, context): """ Hook to build the values of a line from the parser returned values. At @@ -104,8 +104,6 @@ class AccountStatementProfil(Model): :param dict of vals from parser for account.bank.statement.line (called by parser.get_st_line_vals) - :param int/long account_payable: ID of the receivable account to use - :param int/long account_receivable: ID of the payable account to use :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. """ @@ -195,18 +193,13 @@ class AccountStatementProfil(Model): statement_vals, context=context) - if profile.receivable_account_id: - account_receivable = account_payable = profile.receivable_account_id.id - else: - account_receivable, account_payable = statement_obj.get_default_pay_receiv_accounts( - cr, uid, 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, account_payable, account_receivable, statement_id, + cr, uid, parser_vals, statement_id, context) statement_store.append(values) # Hack to bypass ORM poor perfomance. Sob... @@ -251,11 +244,3 @@ class AccountStatementProfil(Model): raise osv.except_osv(_("Statement import error"), _("The statement cannot be created: %s") % st) return statement_id - - -class AccountBankStatementLine(Model): - _inherit = "account.bank.statement.line" - - _columns = { - 'account_id': fields.many2one('account.account', 'Account'), - } diff --git a/account_statement_completion_label/__init__.py b/account_statement_completion_label/__init__.py new file mode 100644 index 00000000..9b4656e6 --- /dev/null +++ b/account_statement_completion_label/__init__.py @@ -0,0 +1,25 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# account_statement_completion_label for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). All Rights Reserved +# @author Benoît GUILLOT +# +# 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 partner +from . import statement + diff --git a/account_statement_completion_label/__openerp__.py b/account_statement_completion_label/__openerp__.py new file mode 100644 index 00000000..96a29127 --- /dev/null +++ b/account_statement_completion_label/__openerp__.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# account_statement_completion_label for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). All Rights Reserved +# @author Benoît GUILLOT +# +# 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 . +# +############################################################################### + +{ + 'name': 'Bank statement completion from label', + 'version': '0.1', + 'category': 'Generic Modules/Others', + 'license': 'AGPL-3', + 'description': """ + Improve the basic rule "Match from statement line label (based on partner field 'Bank Statement Label')" provided by the + Bank statement base completion module. The goal is to match the label field from the bank statement line with a partner and + an account. + For this, you have to create your record in the new class account.statement.label where you can link the label you want with a + partner and an account. + + """, + 'author': 'Akretion', + 'website': 'http://www.akretion.com/', + 'depends': ['account_statement_base_completion'], + 'data': [ + 'partner_view.xml', + 'statement_view.xml', + 'security/ir.model.access.csv', + 'security/ir_rule.xml', + ], + 'demo': [], + 'installable': True, + 'active': False, +} + diff --git a/account_statement_completion_label/partner.py b/account_statement_completion_label/partner.py new file mode 100644 index 00000000..f2e85cb4 --- /dev/null +++ b/account_statement_completion_label/partner.py @@ -0,0 +1,33 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# account_statement_completion_label for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). All Rights Reserved +# @author Benoît GUILLOT +# +# 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 openerp.osv import fields, orm + + +class res_partner(orm.Model): + _inherit = "res.partner" + + _columns = { + 'bank_statement_label': fields.one2many('account.statement.label', + 'partner_id', + 'Bank Statement Label'), + } diff --git a/account_statement_completion_label/partner_view.xml b/account_statement_completion_label/partner_view.xml new file mode 100644 index 00000000..9a7b35b3 --- /dev/null +++ b/account_statement_completion_label/partner_view.xml @@ -0,0 +1,33 @@ + + + + + + + account_bank_statement_import.view.partner.form + res.partner + form + 20 + + + + + + + + + + + + + + + + + + diff --git a/account_statement_completion_label/security/ir.model.access.csv b/account_statement_completion_label/security/ir.model.access.csv new file mode 100644 index 00000000..6a42a84a --- /dev/null +++ b/account_statement_completion_label/security/ir.model.access.csv @@ -0,0 +1,3 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_account_statement_label_user,account.statement.label,model_account_statement_label,account.group_account_user,1,0,0,0 +access_account_statement_label_manager,account.statement.label,model_account_statement_label,account.group_account_manager,1,1,1,1 diff --git a/account_statement_completion_label/security/ir_rule.xml b/account_statement_completion_label/security/ir_rule.xml new file mode 100644 index 00000000..205c4ef7 --- /dev/null +++ b/account_statement_completion_label/security/ir_rule.xml @@ -0,0 +1,14 @@ + + + + + + Multicompany label + + ['|',('company_id','=',False),('company_id','child_of',[user.company_id.id])] + + + + + + diff --git a/account_statement_completion_label/statement.py b/account_statement_completion_label/statement.py new file mode 100644 index 00000000..0d50ae56 --- /dev/null +++ b/account_statement_completion_label/statement.py @@ -0,0 +1,154 @@ +# -*- coding: utf-8 -*- +############################################################################### +# +# account_statement_completion_label for OpenERP +# Copyright (C) 2013 Akretion (http://www.akretion.com). All Rights Reserved +# @author Benoît GUILLOT +# +# 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 openerp.osv import fields, orm +from collections import defaultdict +from openerp.addons.account_statement_base_completion.statement import ErrorTooManyPartner + + +class ErrorTooManyLabel(Exception): + """ + New Exception definition that is raised when more than one label is matched + by the completion rule. + """ + def __init__(self, value): + self.value = value + + def __str__(self): + return repr(self.value) + + +class AccountBankSatement(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" + + def open_completion_label(self, cr, uid, ids, context=None): + return { + 'name': 'Statement Label', + 'view_type': 'form', + 'view_mode': 'tree,form', + 'res_model': 'account.statement.label', + 'type': 'ir.actions.act_window', + 'nodestroy': True, + 'target': False, + } + + +class AccountStatementCompletionRule(orm.Model): + _inherit = "account.statement.completion.rule" + + def get_from_label_and_partner_field(self, cr, uid, st_line, context=None): + """ + Match the partner and the account based on the name field of the + statement line and the table account.statement.label. + If more than one statement label matched, raise the ErrorTooManylabel + error. + + :param int line_id: id 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, + + ...} + """ + st_obj = self.pool.get('account.bank.statement') + statement = st_obj.browse(cr, uid, st_line['statement_id'][0], + context=context) + res = {} + if not context.get('label_memorizer'): + context['label_memorizer'] = defaultdict(list) + for line in statement.line_ids: + cr.execute(""" + SELECT l.partner_id, + l.account_id + FROM account_statement_label as l, + account_bank_statement as s + LEFT JOIN + account_bank_statement_line as st_l + ON + st_l.statement_id = s.id + WHERE + st_l.name ~* l.label + AND + l.profile_id = s.profile_id + AND + st_l.id = %s + """, (line.id,)) + for partner, account in cr.fetchall(): + context['label_memorizer'][line.id].append({'partner_id': partner, + 'account_id': account}) + if st_line['id'] in context['label_memorizer']: + label_info = context['label_memorizer'][st_line['id']] + if len(label_info) > 1: + raise ErrorTooManyPartner(_('Line named "%s" (Ref:%s) was matched by ' + 'more than one statement label.') % + (st_line['name'], st_line['ref'])) + if label_info[0]['partner_id']: + res['partner_id'] = label_info[0]['partner_id'] + res['account_id'] = label_info[0]['account_id'] + return res + + +class AccountStatementLabel(orm.Model): + """Create a new class to map an account statement label to a partner + and a specific account + """ + _name = "account.statement.label" + + _description = "Account Statement Label" + + _columns = { + 'partner_id': fields.many2one('res.partner', 'Partner'), + 'label': fields.char('Bank Statement Label', size=100), + 'account_id': fields.many2one('account.account', 'Account', + required = True, + help='Account corresponding to the label ' + 'for a given partner'), + 'company_id': fields.related('account_id', 'company_id', + type='many2one', + relation='res.company', + string='Company', + store=True, + readonly=True), + 'profile_id': fields.many2one('account.statement.profile', + 'Account Profile'), + } + + _defaults = { + 'company_id': lambda s,cr,uid,c: + s.pool.get('res.company')._company_default_get(cr, uid, + 'account.statement.label', + context=c), + } + + _sql_constraints = [ + ('profile_label_unique', 'unique (label, profile_id, company_id)', + 'You cannot have similar label for the same profile and company'), + ] + + def save_and_close_label(self, cr, uid, ids, context=None): + return {'type': 'ir.actions.act_window_close'} diff --git a/account_statement_completion_label/statement_view.xml b/account_statement_completion_label/statement_view.xml new file mode 100644 index 00000000..d965433c --- /dev/null +++ b/account_statement_completion_label/statement_view.xml @@ -0,0 +1,79 @@ + + + + + + + + account_statement_completion_label.bank_statement.view_form + account.bank.statement + + + + +