diff --git a/account_advanced_reconcile/i18n/fr.po b/account_advanced_reconcile/i18n/fr.po new file mode 100644 index 00000000..b5f20627 --- /dev/null +++ b/account_advanced_reconcile/i18n/fr.po @@ -0,0 +1,90 @@ +# Translation of OpenERP Server. +# This file contains the translation of the following modules: +# * account_advanced_reconcile +# +msgid "" +msgstr "" +"Project-Id-Version: OpenERP Server 6.1\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2012-11-07 12:34+0000\n" +"PO-Revision-Date: 2012-11-07 12:34+0000\n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: account_advanced_reconcile +#: field:easy.reconcile.advanced,partner_ids:0 +#: field:easy.reconcile.advanced.ref,partner_ids:0 +msgid "Restrict on partners" +msgstr "Restriction sur les partenaires" + +#. module: account_advanced_reconcile +#: field:easy.reconcile.advanced,account_id:0 +#: field:easy.reconcile.advanced.ref,account_id:0 +msgid "Account" +msgstr "Compte" + +#. module: account_advanced_reconcile +#: model:ir.model,name:account_advanced_reconcile.model_account_easy_reconcile_method +msgid "reconcile method for account_easy_reconcile" +msgstr "Méthode de lettrage pour le module account_easy_reconcile" + +#. module: account_advanced_reconcile +#: field:easy.reconcile.advanced,date_base_on:0 +#: field:easy.reconcile.advanced.ref,date_base_on:0 +msgid "Date of reconcilation" +msgstr "Date de lettrage" + +#. module: account_advanced_reconcile +#: field:easy.reconcile.advanced,journal_id:0 +#: field:easy.reconcile.advanced.ref,journal_id:0 +msgid "Journal" +msgstr "Journal" + +#. module: account_advanced_reconcile +#: field:easy.reconcile.advanced,account_profit_id:0 +#: field:easy.reconcile.advanced.ref,account_profit_id:0 +msgid "Account Profit" +msgstr "Compte de produit" + +#. module: account_advanced_reconcile +#: field:easy.reconcile.advanced,filter:0 +#: field:easy.reconcile.advanced.ref,filter:0 +msgid "Filter" +msgstr "Filtre" + +#. module: account_advanced_reconcile +#: view:account.easy.reconcile:0 +msgid "Advanced. Partner and Ref" +msgstr "Avancé. Partenaire et Réf." + +#. module: account_advanced_reconcile +#: view:account.easy.reconcile:0 +msgid "Match multiple debit vs multiple credit entries. Allow partial reconcilation. The lines should have the partner, the credit entry ref. is matched vs the debit entry ref. or name." +msgstr "Le Lettrage peut s'effectuer sur plusieurs écritures de débit et crédit. Le Lettrage partiel est autorisé. Les écritures doivent avoir le même partenaire et la référence sur les écritures de crédit doit se retrouver dans la référence ou la description sur les écritures de débit." + +#. module: account_advanced_reconcile +#: model:ir.model,name:account_advanced_reconcile.model_easy_reconcile_advanced +msgid "easy.reconcile.advanced" +msgstr "easy.reconcile.advanced" + +#. module: account_advanced_reconcile +#: field:easy.reconcile.advanced,account_lost_id:0 +#: field:easy.reconcile.advanced.ref,account_lost_id:0 +msgid "Account Lost" +msgstr "Compte de charge" + +#. module: account_advanced_reconcile +#: model:ir.model,name:account_advanced_reconcile.model_easy_reconcile_advanced_ref +msgid "easy.reconcile.advanced.ref" +msgstr "easy.reconcile.advanced.ref" + +#. module: account_advanced_reconcile +#: field:easy.reconcile.advanced,write_off:0 +#: field:easy.reconcile.advanced.ref,write_off:0 +msgid "Write off allowed" +msgstr "Écart autorisé" + diff --git a/account_easy_reconcile/__init__.py b/account_easy_reconcile/__init__.py index 19e90a30..b648751f 100755 --- a/account_easy_reconcile/__init__.py +++ b/account_easy_reconcile/__init__.py @@ -22,3 +22,4 @@ import easy_reconcile import base_reconciliation import simple_reconciliation +import easy_reconcile_history diff --git a/account_easy_reconcile/__openerp__.py b/account_easy_reconcile/__openerp__.py index 82873ab3..ffb44820 100755 --- a/account_easy_reconcile/__openerp__.py +++ b/account_easy_reconcile/__openerp__.py @@ -40,6 +40,11 @@ in order to provide: - a profile a reconciliation can be run manually or by a cron - monitoring of reconcilation runs with a few logs + - this module is also a base to create others + reconciliation methods which can plug in the profiles + - a profile a reconciliation can be run manually or by a cron + - monitoring of reconciliation runs with an history + which keep track of the reconciled entries 2 simple reconciliation methods are integrated in this module, the simple reconciliations works @@ -57,7 +62,10 @@ allows multiple lines and partial. "category" : "Finance", "init_xml" : [], "demo_xml" : [], - "update_xml" : ["easy_reconcile.xml"], + "update_xml" : [ + "easy_reconcile.xml", + "easy_reconcile_history_view.xml", + ], 'license': 'AGPL-3', "auto_install": False, "installable": True, diff --git a/account_easy_reconcile/easy_reconcile.py b/account_easy_reconcile/easy_reconcile.py index 6a2899cd..25b3e370 100644 --- a/account_easy_reconcile/easy_reconcile.py +++ b/account_easy_reconcile/easy_reconcile.py @@ -137,22 +137,39 @@ class account_easy_reconcile(Model): context=context)) return res + def _last_history(self, cr, uid, ids, name, args, context=None): + result = {} + for history in self.browse(cr, uid, ids, context=context): + # history is sorted by date desc + result[history.id] = history.history_ids[0].id + return result + _columns = { 'name': fields.char('Name', size=64, required=True), 'account': fields.many2one('account.account', 'Account', required=True), 'reconcile_method': fields.one2many('account.easy.reconcile.method', 'task_id', 'Method'), 'scheduler': fields.many2one('ir.cron', 'scheduler', readonly=True), - 'rec_log': fields.text('log', readonly=True), 'unreconciled_count': fields.function(_get_total_unrec, - type='integer', string='Fully Unreconciled Entries'), + type='integer', string='Unreconciled Entries'), 'reconciled_partial_count': fields.function(_get_partial_rec, type='integer', string='Partially Reconciled Entries'), + 'history_ids': fields.one2many( + 'easy.reconcile.history', + 'easy_reconcile_id', + string='History'), + 'last_history': + fields.function( + _last_history, + string='Last History', + type='many2one', + relation='easy.reconcile.history', + readonly=True), } def copy_data(self, cr, uid, id, default=None, context=None): if default is None: default = {} - default = dict(default, rec_log=False, scheduler=False) + default = dict(default, scheduler=False) return super(account_easy_reconcile, self).copy_data( cr, uid, id, default=default, context=context) @@ -168,39 +185,69 @@ class account_easy_reconcile(Model): 'filter': rec_method.filter} def run_reconcile(self, cr, uid, ids, context=None): + def find_reconcile_ids(fieldname, move_line_ids): + if not move_line_ids: + return [] + sql = ("SELECT DISTINCT " + fieldname + + " FROM account_move_line " + " WHERE id in %s " + " AND " + fieldname + " IS NOT NULL") + cr.execute(sql, (tuple(move_line_ids),)) + res = cr.fetchall() + return [row[0] for row in res] + if context is None: context = {} - for rec_id in ids: - rec = self.browse(cr, uid, rec_id, context=context) - total_rec = 0 - total_partial_rec = 0 - details = [] - count = 0 - for method in rec.reconcile_method: - count += 1 + for rec in self.browse(cr, uid, ids, context=context): + all_ml_rec_ids = [] + all_ml_partial_ids = [] + for method in rec.reconcile_method: rec_model = self.pool.get(method.name) auto_rec_id = rec_model.create( cr, uid, self._prepare_run_transient(cr, uid, method, context=context), context=context) - rec_ids, partial_ids = rec_model.automatic_reconcile( + ml_rec_ids, ml_partial_ids = rec_model.automatic_reconcile( cr, uid, auto_rec_id, context=context) - details.append(_('method %d : full: %d lines, partial: %d lines') % \ - (count, len(rec_ids), len(partial_ids))) + all_ml_rec_ids += ml_rec_ids + all_ml_partial_ids += ml_partial_ids - total_rec += len(rec_ids) - total_partial_rec += len(partial_ids) + reconcile_ids = find_reconcile_ids( + 'reconcile_id', all_ml_rec_ids) + partial_ids = find_reconcile_ids( + 'reconcile_partial_id', all_ml_partial_ids) - log = self.read(cr, uid, rec_id, ['rec_log'], context=context)['rec_log'] - log_lines = log and log.splitlines() or [] - log_lines[0:0] = [_("%s : %d lines have been fully reconciled" \ - " and %d lines have been partially reconciled (%s)") % \ - (time.strftime(DEFAULT_SERVER_DATETIME_FORMAT), total_rec, - total_partial_rec, ' | '.join(details))] - log = "\n".join(log_lines) - self.write(cr, uid, rec_id, {'rec_log': log}, context=context) + self.pool.get('easy.reconcile.history').create( + cr, + uid, + {'easy_reconcile_id': rec.id, + 'date': fields.datetime.now(), + 'reconcile_ids': [(4, rid) for rid in reconcile_ids], + 'reconcile_partial_ids': [(4, rid) for rid in partial_ids]}, + context=context) return True + def last_history_reconcile(self, cr, uid, rec_id, context=None): + """ Get the last history record for this reconciliation profile + and return the action which opens move lines reconciled + """ + if isinstance(rec_id, (tuple, list)): + assert len(rec_id) == 1, \ + "Only 1 id expected" + rec_id = rec_id[0] + rec = self.browse(cr, uid, rec_id, context=context) + return rec.last_history.open_reconcile() + + def last_history_partial(self, cr, uid, rec_id, context=None): + """ Get the last history record for this reconciliation profile + and return the action which opens move lines reconciled + """ + if isinstance(rec_id, (tuple, list)): + assert len(rec_id) == 1, \ + "Only 1 id expected" + rec_id = rec_id[0] + rec = self.browse(cr, uid, rec_id, context=context) + return rec.last_history.open_partial() diff --git a/account_easy_reconcile/easy_reconcile.xml b/account_easy_reconcile/easy_reconcile.xml index 1bd84c66..7f7f8334 100644 --- a/account_easy_reconcile/easy_reconcile.xml +++ b/account_easy_reconcile/easy_reconcile.xml @@ -20,6 +20,28 @@ +