diff --git a/account_advanced_reconcile/__init__.py b/account_advanced_reconcile/__init__.py index 263cb053..1c643cae 100644 --- a/account_advanced_reconcile/__init__.py +++ b/account_advanced_reconcile/__init__.py @@ -1,5 +1,4 @@ # -*- coding: utf-8 -*- -# -*- coding: utf-8 -*- ############################################################################## # # Author: Guewen Baconnier @@ -20,4 +19,6 @@ # ############################################################################## +import easy_reconcile import base_advanced_reconciliation +import advanced_reconciliation diff --git a/account_advanced_reconcile/advanced_reconciliation.py b/account_advanced_reconcile/advanced_reconciliation.py new file mode 100644 index 00000000..f1297e0a --- /dev/null +++ b/account_advanced_reconcile/advanced_reconciliation.py @@ -0,0 +1,227 @@ +# -*- 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.orm import TransientModel + + +class easy_reconcile_advanced_ref(TransientModel): + + _name = 'easy.reconcile.advanced.ref' + _inherit = 'easy.reconcile.advanced' + _auto = True # False when inherited from AbstractModel + + 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 found 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 returns: + 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 than 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 have to yield its value respecting the orders + 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'].lower().strip(), + move_line['name'].lower().strip())) + + +class easy_reconcile_advanced_tid(TransientModel): + + # tid means for transaction_id + _name = 'easy.reconcile.advanced.tid' + _inherit = 'easy.reconcile.advanced' + _auto = True # False when inherited from AbstractModel + + 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 found 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 returns: + 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 than 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 have to yield its value respecting the orders + 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']) + + prefixes = ('tid_', 'tid_mag_') + refs = [] + if move_line.get('ref'): + lref = move_line['ref'].lower().strip() + refs.append(lref) + refs += ["%s%s" % (s, lref) for s in prefixes] + + if move_line.get('name'): + refs.append(move_line['name'].lower().strip()) + yield ('ref', refs) + diff --git a/account_advanced_reconcile/base_advanced_reconciliation.py b/account_advanced_reconcile/base_advanced_reconciliation.py index e117525d..299ffab2 100644 --- a/account_advanced_reconcile/base_advanced_reconciliation.py +++ b/account_advanced_reconcile/base_advanced_reconciliation.py @@ -25,22 +25,6 @@ from openerp.osv.orm import Model, AbstractModel, TransientModel from openerp.osv import fields -class account_easy_reconcile_method(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 method, payment ref matches with ref or name'), - ('easy.reconcile.advanced.tid', - 'Advanced method, payment Transaction ID matches with ref or name') - ] - return methods - - class easy_reconcile_advanced(AbstractModel): _name = 'easy.reconcile.advanced' @@ -288,207 +272,3 @@ class easy_reconcile_advanced(AbstractModel): return reconciled_ids, partial_reconciled_ids - -class easy_reconcile_advanced_ref(TransientModel): - - _name = 'easy.reconcile.advanced.ref' - _inherit = 'easy.reconcile.advanced' - _auto = True # False when inherited from AbstractModel - - 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 found 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 returns: - 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 than 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 have to yield its value respecting the orders - 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'].lower().strip(), - move_line['name'].lower().strip())) - - -class easy_reconcile_advanced_tid(TransientModel): - - # tid means for transaction_id - _name = 'easy.reconcile.advanced.tid' - _inherit = 'easy.reconcile.advanced' - _auto = True # False when inherited from AbstractModel - - 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 found 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 returns: - 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 than 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 have to yield its value respecting the orders - 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']) - - prefixes = ('tid_', 'tid_mag_') - refs = [] - if move_line.get('ref'): - lref = move_line['ref'].lower().strip() - refs.append(lref) - refs += ["%s%s" % (s, lref) for s in prefixes] - - if move_line.get('name'): - refs.append(move_line['name'].lower().strip()) - yield ('ref', refs) - diff --git a/account_advanced_reconcile/easy_reconcile.py b/account_advanced_reconcile/easy_reconcile.py new file mode 100644 index 00000000..ff5155a1 --- /dev/null +++ b/account_advanced_reconcile/easy_reconcile.py @@ -0,0 +1,38 @@ +# -*- 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.orm import Model + + +class account_easy_reconcile_method(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 method, payment ref matches with ref or name'), + ('easy.reconcile.advanced.tid', + 'Advanced method, payment Transaction ID matches with ref or name') + ] + return methods