diff --git a/account_advanced_reconcile/__init__.py b/account_advanced_reconcile/__init__.py
new file mode 100644
index 00000000..e1a57902
--- /dev/null
+++ b/account_advanced_reconcile/__init__.py
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Contributor: Leonardo Pistone
+# Copyright 2012-2014 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 .
+#
+##############################################################################
+
+from . import easy_reconcile
+from . import base_advanced_reconciliation
+from . import advanced_reconciliation
diff --git a/account_advanced_reconcile/__openerp__.py b/account_advanced_reconcile/__openerp__.py
new file mode 100644
index 00000000..ffe335dc
--- /dev/null
+++ b/account_advanced_reconcile/__openerp__.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Contributor: Leonardo Pistone
+# Copyright 2012-2014 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 .
+#
+##############################################################################
+
+{'name': "Advanced Reconcile",
+ 'version': '1.0',
+ 'author': "Camptocamp,Odoo Community Association (OCA)",
+ 'maintainer': 'Camptocamp',
+ 'category': 'Finance',
+ 'complexity': 'normal',
+ 'depends': ['account_easy_reconcile',
+ ],
+ 'description': """
+Advanced reconciliation methods for the module account_easy_reconcile.
+
+In addition to the features implemented in account_easy_reconcile, which are:
+ - reconciliation facilities for big volume of transactions
+ - setup different profiles of reconciliation by account
+ - each profile can use many methods of reconciliation
+ - 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 reconcilation runs with an history
+
+It implements a basis to created advanced reconciliation methods in a few lines
+of code.
+
+Typically, such a method can be:
+ - Reconcile Journal items if the partner and the ref are equal
+ - Reconcile Journal items if the partner is equal and the ref
+ is the same than ref or name
+ - Reconcile Journal items if the partner is equal and the ref
+ match with a pattern
+
+And they allows:
+ - Reconciliations with multiple credit / multiple debit lines
+ - Partial reconciliations
+ - Write-off amount as well
+
+A method is already implemented in this module, it matches on items:
+ - Partner
+ - Ref on credit move lines should be case insensitive equals to the ref or
+ the name of the debit move line
+
+The base class to find the reconciliations is built to be as efficient as
+possible.
+
+So basically, if you have an invoice with 3 payments (one per month), the first
+month, it will partial reconcile the debit move line with the first payment,
+the second month, it will partial reconcile the debit move line with 2 first
+payments, the third month, it will make the full reconciliation.
+
+This module is perfectly adapted for E-Commerce business where a big volume of
+move lines and so, reconciliations, are involved and payments often come from
+many offices.
+
+ """,
+ 'website': 'http://www.camptocamp.com',
+ 'data': ['easy_reconcile_view.xml',
+ ],
+ 'test': [],
+ 'images': [],
+ 'installable': False,
+ 'auto_install': False,
+ 'license': 'AGPL-3',
+ 'application': True,
+ }
diff --git a/account_advanced_reconcile/advanced_reconciliation.py b/account_advanced_reconcile/advanced_reconciliation.py
new file mode 100644
index 00000000..5ac292c1
--- /dev/null
+++ b/account_advanced_reconcile/advanced_reconciliation.py
@@ -0,0 +1,118 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Copyright 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 .
+#
+##############################################################################
+
+from openerp.osv import orm
+
+
+class easy_reconcile_advanced_ref(orm.TransientModel):
+
+ _name = 'easy.reconcile.advanced.ref'
+ _inherit = 'easy.reconcile.advanced'
+
+ def _skip_line(self, cr, uid, rec, move_line, context=None):
+ """
+ When True is returned on some conditions, the credit move line
+ will be skipped for reconciliation. Can be inherited to
+ skip on some conditions. ie: ref or partner_id is empty.
+ """
+ return not (move_line.get('ref') and move_line.get('partner_id'))
+
+ def _matchers(self, cr, uid, rec, move_line, context=None):
+ """
+ Return the values used as matchers to find the opposite lines
+
+ All the matcher keys in the dict must have their equivalent in
+ the `_opposite_matchers`.
+
+ The values of each matcher key will be searched in the
+ one returned by the `_opposite_matchers`
+
+ Must be inherited to implement the matchers for one method
+
+ For instance, it can return:
+ return ('ref', move_line['rec'])
+
+ or
+ return (('partner_id', move_line['partner_id']),
+ ('ref', "prefix_%s" % move_line['rec']))
+
+ All the matchers have to be found in the opposite lines
+ to consider them as "opposite"
+
+ The matchers will be evaluated in the same order as declared
+ vs the the opposite matchers, so you can gain performance by
+ declaring first the partners with the less computation.
+
+ All matchers should match with their opposite to be considered
+ as "matching".
+ So with the previous example, partner_id and ref have to be
+ equals on the opposite line matchers.
+
+ :return: tuple of tuples (key, value) where the keys are
+ the matchers keys
+ (must be the same than `_opposite_matchers` returns,
+ and their values to match in the opposite lines.
+ A matching key can have multiples values.
+ """
+ return (('partner_id', move_line['partner_id']),
+ ('ref', move_line['ref'].lower().strip()))
+
+ def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
+ """
+ Return the values of the opposite line used as matchers
+ so the line is matched
+
+ Must be inherited to implement the matchers for one method
+ It can be inherited to apply some formatting of fields
+ (strip(), lower() and so on)
+
+ This method is the counterpart of the `_matchers()` method.
+
+ Each matcher has to yield its value respecting the order
+ of the `_matchers()`.
+
+ When a matcher does not correspond, the next matchers won't
+ be evaluated so the ones which need the less computation
+ have to be executed first.
+
+ If the `_matchers()` returns:
+ (('partner_id', move_line['partner_id']),
+ ('ref', move_line['ref']))
+
+ Here, you should yield :
+ yield ('partner_id', move_line['partner_id'])
+ yield ('ref', move_line['ref'])
+
+ Note that a matcher can contain multiple values, as instance,
+ if for a move line, you want to search from its `ref` in the
+ `ref` or `name` fields of the opposite move lines, you have to
+ yield ('partner_id', move_line['partner_id'])
+ yield ('ref', (move_line['ref'], move_line['name'])
+
+ An OR is used between the values for the same key.
+ An AND is used between the differents keys.
+
+ :param dict move_line: values of the move_line
+ :yield: matchers as tuple ('matcher key', value(s))
+ """
+ yield ('partner_id', move_line['partner_id'])
+ yield ('ref', ((move_line['ref'] or '').lower().strip(),
+ move_line['name'].lower().strip()))
diff --git a/account_advanced_reconcile/base_advanced_reconciliation.py b/account_advanced_reconcile/base_advanced_reconciliation.py
new file mode 100644
index 00000000..a9fe439c
--- /dev/null
+++ b/account_advanced_reconcile/base_advanced_reconciliation.py
@@ -0,0 +1,287 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Contributor: Leonardo Pistone
+# Copyright 2012-2014 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 logging
+
+from itertools import product
+from openerp.osv import orm
+from openerp.tools.translate import _
+
+_logger = logging.getLogger(__name__)
+
+
+class easy_reconcile_advanced(orm.AbstractModel):
+ _name = 'easy.reconcile.advanced'
+ _inherit = 'easy.reconcile.base'
+
+ def _query_debit(self, cr, uid, rec, context=None):
+ """Select all move (debit>0) as candidate. """
+ select = self._select(rec)
+ sql_from = self._from(rec)
+ where, params = self._where(rec)
+ where += " AND account_move_line.debit > 0 "
+ where2, params2 = self._get_filter(cr, uid, rec, context=context)
+ query = ' '.join((select, sql_from, where, where2))
+ cr.execute(query, params + params2)
+ return cr.dictfetchall()
+
+ def _query_credit(self, cr, uid, rec, context=None):
+ """Select all move (credit>0) as candidate. """
+ select = self._select(rec)
+ sql_from = self._from(rec)
+ where, params = self._where(rec)
+ where += " AND account_move_line.credit > 0 "
+ where2, params2 = self._get_filter(cr, uid, rec, context=context)
+ query = ' '.join((select, sql_from, where, where2))
+ cr.execute(query, params + params2)
+ return cr.dictfetchall()
+
+ def _matchers(self, cr, uid, rec, move_line, context=None):
+ """
+ Return the values used as matchers to find the opposite lines
+
+ All the matcher keys in the dict must have their equivalent in
+ the `_opposite_matchers`.
+
+ The values of each matcher key will be searched in the
+ one returned by the `_opposite_matchers`
+
+ Must be inherited to implement the matchers for one method
+
+ As instance, it can return:
+ return ('ref', move_line['rec'])
+
+ or
+ return (('partner_id', move_line['partner_id']),
+ ('ref', "prefix_%s" % move_line['rec']))
+
+ All the matchers have to be found in the opposite lines
+ to consider them as "opposite"
+
+ The matchers will be evaluated in the same order as declared
+ vs the the opposite matchers, so you can gain performance by
+ declaring first the partners with the less computation.
+
+ All matchers should match with their opposite to be considered
+ as "matching".
+ So with the previous example, partner_id and ref have to be
+ equals on the opposite line matchers.
+
+ :return: tuple of tuples (key, value) where the keys are
+ the matchers keys
+ (must be the same than `_opposite_matchers` returns,
+ and their values to match in the opposite lines.
+ A matching key can have multiples values.
+ """
+ raise NotImplementedError
+
+ def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
+ """
+ Return the values of the opposite line used as matchers
+ so the line is matched
+
+ Must be inherited to implement the matchers for one method
+ It can be inherited to apply some formatting of fields
+ (strip(), lower() and so on)
+
+ This method is the counterpart of the `_matchers()` method.
+
+ Each matcher has to yield its value respecting the order
+ of the `_matchers()`.
+
+ When a matcher does not correspond, the next matchers won't
+ be evaluated so the ones which need the less computation
+ have to be executed first.
+
+ If the `_matchers()` returns:
+ (('partner_id', move_line['partner_id']),
+ ('ref', move_line['ref']))
+
+ Here, you should yield :
+ yield ('partner_id', move_line['partner_id'])
+ yield ('ref', move_line['ref'])
+
+ Note that a matcher can contain multiple values, as instance,
+ if for a move line, you want to search from its `ref` in the
+ `ref` or `name` fields of the opposite move lines, you have to
+ yield ('partner_id', move_line['partner_id'])
+ yield ('ref', (move_line['ref'], move_line['name'])
+
+ An OR is used between the values for the same key.
+ An AND is used between the differents keys.
+
+ :param dict move_line: values of the move_line
+ :yield: matchers as tuple ('matcher key', value(s))
+ """
+ raise NotImplementedError
+
+ @staticmethod
+ def _compare_values(key, value, opposite_value):
+ """Can be inherited to modify the equality condition
+ specifically according to the matcher key (maybe using
+ a like operator instead of equality on 'ref' as instance)
+ """
+ # consider that empty vals are not valid matchers
+ # it can still be inherited for some special cases
+ # where it would be allowed
+ if not (value and opposite_value):
+ return False
+
+ if value == opposite_value:
+ return True
+ return False
+
+ @staticmethod
+ def _compare_matcher_values(key, values, opposite_values):
+ """ Compare every values from a matcher vs an opposite matcher
+ and return True if it matches
+ """
+ for value, ovalue in product(values, opposite_values):
+ # we do not need to compare all values, if one matches
+ # we are done
+ if easy_reconcile_advanced._compare_values(key, value, ovalue):
+ return True
+ return False
+
+ @staticmethod
+ def _compare_matchers(matcher, opposite_matcher):
+ """
+ Prepare and check the matchers to compare
+ """
+ mkey, mvalue = matcher
+ omkey, omvalue = opposite_matcher
+ assert mkey == omkey, \
+ (_("A matcher %s is compared with a matcher %s, the _matchers and "
+ "_opposite_matchers are probably wrong") % (mkey, omkey))
+ if not isinstance(mvalue, (list, tuple)):
+ mvalue = mvalue,
+ if not isinstance(omvalue, (list, tuple)):
+ omvalue = omvalue,
+ return easy_reconcile_advanced._compare_matcher_values(mkey, mvalue,
+ omvalue)
+
+ def _compare_opposite(self, cr, uid, rec, move_line, opposite_move_line,
+ matchers, context=None):
+ """ Iterate over the matchers of the move lines vs opposite move lines
+ and if they all match, return True.
+
+ If all the matchers match for a move line and an opposite move line,
+ they are candidate for a reconciliation.
+ """
+ opp_matchers = self._opposite_matchers(cr, uid, rec,
+ opposite_move_line,
+ context=context)
+ for matcher in matchers:
+ try:
+ opp_matcher = opp_matchers.next()
+ except StopIteration:
+ # if you fall here, you probably missed to put a `yield`
+ # in `_opposite_matchers()`
+ raise ValueError("Missing _opposite_matcher: %s" % matcher[0])
+
+ if not self._compare_matchers(matcher, opp_matcher):
+ # if any of the matcher fails, the opposite line
+ # is not a valid counterpart
+ # directly returns so the next yield of _opposite_matchers
+ # are not evaluated
+ return False
+
+ return True
+
+ def _search_opposites(self, cr, uid, rec, move_line, opposite_move_lines,
+ context=None):
+ """Search the opposite move lines for a move line
+
+ :param dict move_line: the move line for which we search opposites
+ :param list opposite_move_lines: list of dict of move lines values,
+ the move lines we want to search for
+ :return: list of matching lines
+ """
+ matchers = self._matchers(cr, uid, rec, move_line, context=context)
+ return [op for op in opposite_move_lines if
+ self._compare_opposite(
+ cr, uid, rec, move_line, op, matchers, context=context)]
+
+ def _action_rec(self, cr, uid, rec, context=None):
+ credit_lines = self._query_credit(cr, uid, rec, context=context)
+ debit_lines = self._query_debit(cr, uid, rec, context=context)
+ result = self._rec_auto_lines_advanced(
+ cr, uid, rec, credit_lines, debit_lines, context=context)
+ return result
+
+ def _skip_line(self, cr, uid, rec, move_line, context=None):
+ """
+ When True is returned on some conditions, the credit move line
+ will be skipped for reconciliation. Can be inherited to
+ skip on some conditions. ie: ref or partner_id is empty.
+ """
+ return False
+
+ def _rec_auto_lines_advanced(self, cr, uid, rec, credit_lines, debit_lines,
+ context=None):
+ """ Advanced reconciliation main loop """
+ reconciled_ids = []
+ partial_reconciled_ids = []
+ reconcile_groups = []
+ _logger.info("%d credit lines to reconcile", len(credit_lines))
+ for idx, credit_line in enumerate(credit_lines, start=1):
+ if idx % 50 == 0:
+ _logger.info("... %d/%d credit lines inspected ...", idx,
+ len(credit_lines))
+ if self._skip_line(cr, uid, rec, credit_line, context=context):
+ continue
+ opposite_lines = self._search_opposites(
+ cr, uid, rec, credit_line, debit_lines, context=context)
+ if not opposite_lines:
+ continue
+ opposite_ids = [l['id'] for l in opposite_lines]
+ line_ids = opposite_ids + [credit_line['id']]
+ for group in reconcile_groups:
+ if any([lid in group for lid in opposite_ids]):
+ _logger.debug("New lines %s matched with an existing "
+ "group %s", line_ids, group)
+ group.update(line_ids)
+ break
+ else:
+ _logger.debug("New group of lines matched %s", line_ids)
+ reconcile_groups.append(set(line_ids))
+ lines_by_id = dict([(l['id'], l) for l in credit_lines + debit_lines])
+ _logger.info("Found %d groups to reconcile", len(reconcile_groups))
+ for group_count, reconcile_group_ids in enumerate(reconcile_groups,
+ start=1):
+ _logger.debug("Reconciling group %d/%d with ids %s",
+ group_count, len(reconcile_groups),
+ reconcile_group_ids)
+ group_lines = [lines_by_id[lid] for lid in reconcile_group_ids]
+ reconciled, full = self._reconcile_lines(
+ cr, uid, rec, group_lines, allow_partial=True, context=context)
+ if reconciled and full:
+ reconciled_ids += reconcile_group_ids
+ elif reconciled:
+ partial_reconciled_ids += reconcile_group_ids
+
+ if (context['commit_every'] and
+ group_count % context['commit_every'] == 0):
+ cr.commit()
+ _logger.info("Commit the reconciliations after %d groups",
+ group_count)
+ _logger.info("Reconciliation is over")
+ return reconciled_ids, partial_reconciled_ids
diff --git a/account_advanced_reconcile/easy_reconcile.py b/account_advanced_reconcile/easy_reconcile.py
new file mode 100644
index 00000000..5506917b
--- /dev/null
+++ b/account_advanced_reconcile/easy_reconcile.py
@@ -0,0 +1,36 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Guewen Baconnier
+# Copyright 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 .
+#
+##############################################################################
+
+from openerp.osv import orm
+
+
+class account_easy_reconcile_method(orm.Model):
+
+ _inherit = 'account.easy.reconcile.method'
+
+ def _get_all_rec_method(self, cr, uid, context=None):
+ methods = super(account_easy_reconcile_method, self).\
+ _get_all_rec_method(cr, uid, context=context)
+ methods += [
+ ('easy.reconcile.advanced.ref',
+ 'Advanced. Partner and Ref.'),
+ ]
+ return methods
diff --git a/account_advanced_reconcile/easy_reconcile_view.xml b/account_advanced_reconcile/easy_reconcile_view.xml
new file mode 100644
index 00000000..7d35927d
--- /dev/null
+++ b/account_advanced_reconcile/easy_reconcile_view.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ account.easy.reconcile.form
+ account.easy.reconcile
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/account_advanced_reconcile/i18n/account_advanced_reconcile.pot b/account_advanced_reconcile/i18n/account_advanced_reconcile.pot
new file mode 100644
index 00000000..98382751
--- /dev/null
+++ b/account_advanced_reconcile/i18n/account_advanced_reconcile.pot
@@ -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 7.0\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2014-01-21 11:54+0000\n"
+"PO-Revision-Date: 2014-01-21 11:54+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 ""
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,account_id:0
+#: field:easy.reconcile.advanced.ref,account_id:0
+msgid "Account"
+msgstr ""
+
+#. module: account_advanced_reconcile
+#: model:ir.model,name:account_advanced_reconcile.model_account_easy_reconcile_method
+msgid "reconcile method for account_easy_reconcile"
+msgstr ""
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,journal_id:0
+#: field:easy.reconcile.advanced.ref,journal_id:0
+msgid "Journal"
+msgstr ""
+
+#. 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 ""
+
+#. module: account_advanced_reconcile
+#: view:account.easy.reconcile:0
+msgid "Match multiple debit vs multiple credit entries. Allow partial reconciliation. The lines should have the partner, the credit entry ref. is matched vs the debit entry ref. or name."
+msgstr ""
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,filter:0
+#: field:easy.reconcile.advanced.ref,filter:0
+msgid "Filter"
+msgstr ""
+
+#. module: account_advanced_reconcile
+#: view:account.easy.reconcile:0
+msgid "Advanced. Partner and Ref"
+msgstr ""
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,date_base_on:0
+#: field:easy.reconcile.advanced.ref,date_base_on:0
+msgid "Date of reconciliation"
+msgstr ""
+
+#. module: account_advanced_reconcile
+#: model:ir.model,name:account_advanced_reconcile.model_easy_reconcile_advanced
+msgid "easy.reconcile.advanced"
+msgstr ""
+
+#. 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 ""
+
+#. module: account_advanced_reconcile
+#: model:ir.model,name:account_advanced_reconcile.model_easy_reconcile_advanced_ref
+msgid "easy.reconcile.advanced.ref"
+msgstr ""
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,write_off:0
+#: field:easy.reconcile.advanced.ref,write_off:0
+msgid "Write off allowed"
+msgstr ""
+
diff --git a/account_advanced_reconcile/i18n/es.po b/account_advanced_reconcile/i18n/es.po
new file mode 100644
index 00000000..cc47462f
--- /dev/null
+++ b/account_advanced_reconcile/i18n/es.po
@@ -0,0 +1,98 @@
+# Spanish translation for banking-addons
+# Copyright (c) 2014 Rosetta Contributors and Canonical Ltd 2014
+# This file is distributed under the same license as the banking-addons package.
+# FIRST AUTHOR , 2014.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: banking-addons\n"
+"Report-Msgid-Bugs-To: FULL NAME \n"
+"POT-Creation-Date: 2014-01-21 11:54+0000\n"
+"PO-Revision-Date: 2014-06-05 22:30+0000\n"
+"Last-Translator: Pedro Manuel Baeza \n"
+"Language-Team: Spanish \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2014-06-06 06:36+0000\n"
+"X-Generator: Launchpad (build 17031)\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 "Restringir a las empresas"
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,account_id:0
+#: field:easy.reconcile.advanced.ref,account_id:0
+msgid "Account"
+msgstr "Cuenta"
+
+#. 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étodo de conciliación para account_easy_reconcile"
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,journal_id:0
+#: field:easy.reconcile.advanced.ref,journal_id:0
+msgid "Journal"
+msgstr "Diario"
+
+#. 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 "Cuenta de ganancias"
+
+#. module: account_advanced_reconcile
+#: view:account.easy.reconcile:0
+msgid ""
+"Match multiple debit vs multiple credit entries. Allow partial "
+"reconciliation. The lines should have the partner, the credit entry ref. is "
+"matched vs the debit entry ref. or name."
+msgstr ""
+"Casa múltiples líneas del debe con múltiples líneas del haber. Permite "
+"conciliación parcial. Las líneas deben tener la empresa, la referencia de la "
+"línea del haber se casa contra la referencia de la línea del debe o el "
+"nombre."
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,filter:0
+#: field:easy.reconcile.advanced.ref,filter:0
+msgid "Filter"
+msgstr "Filtro"
+
+#. module: account_advanced_reconcile
+#: view:account.easy.reconcile:0
+msgid "Advanced. Partner and Ref"
+msgstr "Avanzado. Empresa y referencia"
+
+#. module: account_advanced_reconcile
+#: field:easy.reconcile.advanced,date_base_on:0
+#: field:easy.reconcile.advanced.ref,date_base_on:0
+msgid "Date of reconciliation"
+msgstr "Fecha de conciliación"
+
+#. 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 "Cuenta de pérdidas"
+
+#. 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 "Desajuste permitido"
diff --git a/account_advanced_reconcile/i18n/fr.po b/account_advanced_reconcile/i18n/fr.po
new file mode 100644
index 00000000..0c3e9eb9
--- /dev/null
+++ b/account_advanced_reconcile/i18n/fr.po
@@ -0,0 +1,98 @@
+# 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: 2014-01-21 11:54+0000\n"
+"PO-Revision-Date: 2014-03-21 15:24+0000\n"
+"Last-Translator: Guewen Baconnier @ Camptocamp \n"
+"Language-Team: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Launchpad-Export-Date: 2014-05-22 06:49+0000\n"
+"X-Generator: Launchpad (build 17017)\n"
+"Language: \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,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
+#: view:account.easy.reconcile:0
+msgid ""
+"Match multiple debit vs multiple credit entries. Allow partial "
+"reconciliation. 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
+#: 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
+#: field:easy.reconcile.advanced,date_base_on:0
+#: field:easy.reconcile.advanced.ref,date_base_on:0
+msgid "Date of reconciliation"
+msgstr "Date de lettrage"
+
+#. 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_advanced_reconcile/res_config.py b/account_advanced_reconcile/res_config.py
new file mode 100644
index 00000000..cb827ab3
--- /dev/null
+++ b/account_advanced_reconcile/res_config.py
@@ -0,0 +1,59 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# Author: Leonardo Pistone
+# Copyright 2014 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 .
+#
+##############################################################################
+
+from openerp.osv import orm, fields
+
+
+class AccountConfigSettings(orm.TransientModel):
+ _inherit = 'account.config.settings'
+
+ _columns = {
+ 'reconciliation_commit_every': fields.related(
+ 'company_id',
+ 'reconciliation_commit_every',
+ type='integer',
+ string='How often to commit when performing automatic '
+ 'reconciliation.',
+ help="""Leave zero to commit only at the end of the process."""),
+ }
+
+ def onchange_company_id(self, cr, uid, ids, company_id, context=None):
+ company_obj = self.pool['res.company']
+
+ result = super(AccountConfigSettings, self).onchange_company_id(
+ cr, uid, ids, company_id, context=None)
+
+ if company_id:
+ company = company_obj.browse(cr, uid, company_id, context=context)
+ result['value']['reconciliation_commit_every'] = (
+ company.reconciliation_commit_every
+ )
+ return result
+
+
+class Company(orm.Model):
+ _inherit = "res.company"
+ _columns = {
+ 'reconciliation_commit_every': fields.integer(
+ string='How often to commit when performing automatic '
+ 'reconciliation.',
+ help="""Leave zero to commit only at the end of the process."""),
+ }
diff --git a/account_advanced_reconcile/res_config_view.xml b/account_advanced_reconcile/res_config_view.xml
new file mode 100644
index 00000000..8badc32e
--- /dev/null
+++ b/account_advanced_reconcile/res_config_view.xml
@@ -0,0 +1,24 @@
+
+
+
+
+ account settings
+ account.config.settings
+
+
+
+
+
+
+