mirror of
https://github.com/OCA/account-reconcile.git
synced 2025-01-20 12:27:39 +02:00
Port models to API 8.0
This commit is contained in:
@@ -1,25 +1 @@
|
|||||||
# -*- coding: utf-8 -*-
|
from . import models
|
||||||
##############################################################################
|
|
||||||
#
|
|
||||||
# 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 <http://www.gnu.org/licenses/>.
|
|
||||||
#
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
from . import easy_reconcile
|
|
||||||
from . import base_advanced_reconciliation
|
|
||||||
from . import advanced_reconciliation
|
|
||||||
|
|||||||
25
account_advanced_reconcile/models/__init__.py
Normal file
25
account_advanced_reconcile/models/__init__.py
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
##############################################################################
|
||||||
|
|
||||||
|
from . import easy_reconcile
|
||||||
|
from . import base_advanced_reconciliation
|
||||||
|
from . import advanced_reconciliation
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
#
|
||||||
#
|
#
|
||||||
# Author: Guewen Baconnier
|
# Author: Guewen Baconnier
|
||||||
# Copyright 2012 Camptocamp SA
|
# Copyright 2012-2015 Camptocamp SA
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
@@ -17,17 +17,17 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
#
|
||||||
|
from openerp import models, api
|
||||||
from openerp.osv import orm
|
|
||||||
|
|
||||||
|
|
||||||
class easy_reconcile_advanced_ref(orm.TransientModel):
|
class EasyReconcileAdvancedRef(models.TransientModel):
|
||||||
|
|
||||||
_name = 'easy.reconcile.advanced.ref'
|
_name = 'easy.reconcile.advanced.ref'
|
||||||
_inherit = 'easy.reconcile.advanced'
|
_inherit = 'easy.reconcile.advanced'
|
||||||
|
|
||||||
def _skip_line(self, cr, uid, rec, move_line, context=None):
|
@api.multi
|
||||||
|
def _skip_line(self, move_line):
|
||||||
"""
|
"""
|
||||||
When True is returned on some conditions, the credit move line
|
When True is returned on some conditions, the credit move line
|
||||||
will be skipped for reconciliation. Can be inherited to
|
will be skipped for reconciliation. Can be inherited to
|
||||||
@@ -35,7 +35,8 @@ class easy_reconcile_advanced_ref(orm.TransientModel):
|
|||||||
"""
|
"""
|
||||||
return not (move_line.get('ref') and move_line.get('partner_id'))
|
return not (move_line.get('ref') and move_line.get('partner_id'))
|
||||||
|
|
||||||
def _matchers(self, cr, uid, rec, move_line, context=None):
|
@api.multi
|
||||||
|
def _matchers(self, move_line):
|
||||||
"""
|
"""
|
||||||
Return the values used as matchers to find the opposite lines
|
Return the values used as matchers to find the opposite lines
|
||||||
|
|
||||||
@@ -75,7 +76,8 @@ class easy_reconcile_advanced_ref(orm.TransientModel):
|
|||||||
return (('partner_id', move_line['partner_id']),
|
return (('partner_id', move_line['partner_id']),
|
||||||
('ref', move_line['ref'].lower().strip()))
|
('ref', move_line['ref'].lower().strip()))
|
||||||
|
|
||||||
def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
|
@api.multi
|
||||||
|
def _opposite_matchers(self, move_line):
|
||||||
"""
|
"""
|
||||||
Return the values of the opposite line used as matchers
|
Return the values of the opposite line used as matchers
|
||||||
so the line is matched
|
so the line is matched
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
#
|
||||||
#
|
#
|
||||||
# Author: Guewen Baconnier
|
# Author: Guewen Baconnier
|
||||||
# Contributor: Leonardo Pistone
|
# Contributor: Leonardo Pistone
|
||||||
# Copyright 2012-2014 Camptocamp SA
|
# Copyright 2012-2015 Camptocamp SA
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
@@ -18,43 +18,46 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
#
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from itertools import product
|
from itertools import product
|
||||||
from openerp.osv import orm
|
from openerp import models, api
|
||||||
from openerp.tools.translate import _
|
from openerp.tools.translate import _
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class easy_reconcile_advanced(orm.AbstractModel):
|
class EasyReconcileAdvanced(models.AbstractModel):
|
||||||
_name = 'easy.reconcile.advanced'
|
_name = 'easy.reconcile.advanced'
|
||||||
_inherit = 'easy.reconcile.base'
|
_inherit = 'easy.reconcile.base'
|
||||||
|
|
||||||
def _query_debit(self, cr, uid, rec, context=None):
|
@api.multi
|
||||||
|
def _query_debit(self):
|
||||||
"""Select all move (debit>0) as candidate. """
|
"""Select all move (debit>0) as candidate. """
|
||||||
select = self._select(rec)
|
select = self._select()
|
||||||
sql_from = self._from(rec)
|
sql_from = self._from()
|
||||||
where, params = self._where(rec)
|
where, params = self._where()
|
||||||
where += " AND account_move_line.debit > 0 "
|
where += " AND account_move_line.debit > 0 "
|
||||||
where2, params2 = self._get_filter(cr, uid, rec, context=context)
|
where2, params2 = self._get_filter()
|
||||||
query = ' '.join((select, sql_from, where, where2))
|
query = ' '.join((select, sql_from, where, where2))
|
||||||
cr.execute(query, params + params2)
|
self.env.cr.execute(query, params + params2)
|
||||||
return cr.dictfetchall()
|
return self.env.cr.dictfetchall()
|
||||||
|
|
||||||
def _query_credit(self, cr, uid, rec, context=None):
|
@api.multi
|
||||||
|
def _query_credit(self):
|
||||||
"""Select all move (credit>0) as candidate. """
|
"""Select all move (credit>0) as candidate. """
|
||||||
select = self._select(rec)
|
select = self._select()
|
||||||
sql_from = self._from(rec)
|
sql_from = self._from()
|
||||||
where, params = self._where(rec)
|
where, params = self._where()
|
||||||
where += " AND account_move_line.credit > 0 "
|
where += " AND account_move_line.credit > 0 "
|
||||||
where2, params2 = self._get_filter(cr, uid, rec, context=context)
|
where2, params2 = self._get_filter()
|
||||||
query = ' '.join((select, sql_from, where, where2))
|
query = ' '.join((select, sql_from, where, where2))
|
||||||
cr.execute(query, params + params2)
|
self.env.cr.execute(query, params + params2)
|
||||||
return cr.dictfetchall()
|
return self.env.cr.dictfetchall()
|
||||||
|
|
||||||
def _matchers(self, cr, uid, rec, move_line, context=None):
|
@api.multi
|
||||||
|
def _matchers(self, move_line):
|
||||||
"""
|
"""
|
||||||
Return the values used as matchers to find the opposite lines
|
Return the values used as matchers to find the opposite lines
|
||||||
|
|
||||||
@@ -93,7 +96,8 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
"""
|
"""
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
def _opposite_matchers(self, cr, uid, rec, move_line, context=None):
|
@api.multi
|
||||||
|
def _opposite_matchers(self, move_line):
|
||||||
"""
|
"""
|
||||||
Return the values of the opposite line used as matchers
|
Return the values of the opposite line used as matchers
|
||||||
so the line is matched
|
so the line is matched
|
||||||
@@ -157,7 +161,7 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
for value, ovalue in product(values, opposite_values):
|
for value, ovalue in product(values, opposite_values):
|
||||||
# we do not need to compare all values, if one matches
|
# we do not need to compare all values, if one matches
|
||||||
# we are done
|
# we are done
|
||||||
if easy_reconcile_advanced._compare_values(key, value, ovalue):
|
if EasyReconcileAdvanced._compare_values(key, value, ovalue):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -175,20 +179,18 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
mvalue = mvalue,
|
mvalue = mvalue,
|
||||||
if not isinstance(omvalue, (list, tuple)):
|
if not isinstance(omvalue, (list, tuple)):
|
||||||
omvalue = omvalue,
|
omvalue = omvalue,
|
||||||
return easy_reconcile_advanced._compare_matcher_values(mkey, mvalue,
|
return EasyReconcileAdvanced._compare_matcher_values(
|
||||||
omvalue)
|
mkey, mvalue, omvalue)
|
||||||
|
|
||||||
def _compare_opposite(self, cr, uid, rec, move_line, opposite_move_line,
|
@api.multi
|
||||||
matchers, context=None):
|
def _compare_opposite(self, move_line, opposite_move_line, matchers):
|
||||||
""" Iterate over the matchers of the move lines vs opposite move lines
|
""" Iterate over the matchers of the move lines vs opposite move lines
|
||||||
and if they all match, return True.
|
and if they all match, return True.
|
||||||
|
|
||||||
If all the matchers match for a move line and an opposite move line,
|
If all the matchers match for a move line and an opposite move line,
|
||||||
they are candidate for a reconciliation.
|
they are candidate for a reconciliation.
|
||||||
"""
|
"""
|
||||||
opp_matchers = self._opposite_matchers(cr, uid, rec,
|
opp_matchers = self._opposite_matchers(opposite_move_line)
|
||||||
opposite_move_line,
|
|
||||||
context=context)
|
|
||||||
for matcher in matchers:
|
for matcher in matchers:
|
||||||
try:
|
try:
|
||||||
opp_matcher = opp_matchers.next()
|
opp_matcher = opp_matchers.next()
|
||||||
@@ -206,8 +208,8 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def _search_opposites(self, cr, uid, rec, move_line, opposite_move_lines,
|
@api.multi
|
||||||
context=None):
|
def _search_opposites(self, move_line, opposite_move_lines):
|
||||||
"""Search the opposite move lines for a move line
|
"""Search the opposite move lines for a move line
|
||||||
|
|
||||||
:param dict move_line: the move line for which we search opposites
|
:param dict move_line: the move line for which we search opposites
|
||||||
@@ -215,19 +217,19 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
the move lines we want to search for
|
the move lines we want to search for
|
||||||
:return: list of matching lines
|
:return: list of matching lines
|
||||||
"""
|
"""
|
||||||
matchers = self._matchers(cr, uid, rec, move_line, context=context)
|
matchers = self._matchers(move_line)
|
||||||
return [op for op in opposite_move_lines if
|
return [op for op in opposite_move_lines if
|
||||||
self._compare_opposite(
|
self._compare_opposite(move_line, op, matchers)]
|
||||||
cr, uid, rec, move_line, op, matchers, context=context)]
|
|
||||||
|
|
||||||
def _action_rec(self, cr, uid, rec, context=None):
|
@api.multi
|
||||||
credit_lines = self._query_credit(cr, uid, rec, context=context)
|
def _action_rec(self):
|
||||||
debit_lines = self._query_debit(cr, uid, rec, context=context)
|
credit_lines = self._query_credit()
|
||||||
result = self._rec_auto_lines_advanced(
|
debit_lines = self._query_debit()
|
||||||
cr, uid, rec, credit_lines, debit_lines, context=context)
|
result = self._rec_auto_lines_advanced(credit_lines, debit_lines)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
def _skip_line(self, cr, uid, rec, move_line, context=None):
|
@api.multi
|
||||||
|
def _skip_line(self, move_line):
|
||||||
"""
|
"""
|
||||||
When True is returned on some conditions, the credit move line
|
When True is returned on some conditions, the credit move line
|
||||||
will be skipped for reconciliation. Can be inherited to
|
will be skipped for reconciliation. Can be inherited to
|
||||||
@@ -235,8 +237,8 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
"""
|
"""
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _rec_auto_lines_advanced(self, cr, uid, rec, credit_lines, debit_lines,
|
@api.multi
|
||||||
context=None):
|
def _rec_auto_lines_advanced(self, credit_lines, debit_lines):
|
||||||
""" Advanced reconciliation main loop """
|
""" Advanced reconciliation main loop """
|
||||||
reconciled_ids = []
|
reconciled_ids = []
|
||||||
partial_reconciled_ids = []
|
partial_reconciled_ids = []
|
||||||
@@ -246,10 +248,9 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
if idx % 50 == 0:
|
if idx % 50 == 0:
|
||||||
_logger.info("... %d/%d credit lines inspected ...", idx,
|
_logger.info("... %d/%d credit lines inspected ...", idx,
|
||||||
len(credit_lines))
|
len(credit_lines))
|
||||||
if self._skip_line(cr, uid, rec, credit_line, context=context):
|
if self._skip_line(credit_line):
|
||||||
continue
|
continue
|
||||||
opposite_lines = self._search_opposites(
|
opposite_lines = self._search_opposites(credit_line, debit_lines)
|
||||||
cr, uid, rec, credit_line, debit_lines, context=context)
|
|
||||||
if not opposite_lines:
|
if not opposite_lines:
|
||||||
continue
|
continue
|
||||||
opposite_ids = [l['id'] for l in opposite_lines]
|
opposite_ids = [l['id'] for l in opposite_lines]
|
||||||
@@ -272,15 +273,15 @@ class easy_reconcile_advanced(orm.AbstractModel):
|
|||||||
reconcile_group_ids)
|
reconcile_group_ids)
|
||||||
group_lines = [lines_by_id[lid] for lid in reconcile_group_ids]
|
group_lines = [lines_by_id[lid] for lid in reconcile_group_ids]
|
||||||
reconciled, full = self._reconcile_lines(
|
reconciled, full = self._reconcile_lines(
|
||||||
cr, uid, rec, group_lines, allow_partial=True, context=context)
|
group_lines, allow_partial=True)
|
||||||
if reconciled and full:
|
if reconciled and full:
|
||||||
reconciled_ids += reconcile_group_ids
|
reconciled_ids += reconcile_group_ids
|
||||||
elif reconciled:
|
elif reconciled:
|
||||||
partial_reconciled_ids += reconcile_group_ids
|
partial_reconciled_ids += reconcile_group_ids
|
||||||
|
|
||||||
if (context['commit_every'] and
|
if (self.env.context.get('commit_every') and
|
||||||
group_count % context['commit_every'] == 0):
|
group_count % self.env.context['commit_every'] == 0):
|
||||||
cr.commit()
|
self.env.cr.commit()
|
||||||
_logger.info("Commit the reconciliations after %d groups",
|
_logger.info("Commit the reconciliations after %d groups",
|
||||||
group_count)
|
group_count)
|
||||||
_logger.info("Reconciliation is over")
|
_logger.info("Reconciliation is over")
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
#
|
||||||
#
|
#
|
||||||
# Author: Guewen Baconnier
|
# Author: Guewen Baconnier
|
||||||
# Copyright 2012 Camptocamp SA
|
# Copyright 2012 Camptocamp SA
|
||||||
@@ -17,18 +17,17 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
#
|
||||||
|
from openerp import models, api
|
||||||
from openerp.osv import orm
|
|
||||||
|
|
||||||
|
|
||||||
class account_easy_reconcile_method(orm.Model):
|
class AccountEasyReconcileMethod(models.Model):
|
||||||
|
|
||||||
_inherit = 'account.easy.reconcile.method'
|
_inherit = 'account.easy.reconcile.method'
|
||||||
|
|
||||||
def _get_all_rec_method(self, cr, uid, context=None):
|
@api.multi
|
||||||
methods = super(account_easy_reconcile_method, self).\
|
def _get_all_rec_method(self):
|
||||||
_get_all_rec_method(cr, uid, context=context)
|
methods = super(AccountEasyReconcileMethod, self
|
||||||
|
)._get_all_rec_method()
|
||||||
methods += [
|
methods += [
|
||||||
('easy.reconcile.advanced.ref',
|
('easy.reconcile.advanced.ref',
|
||||||
'Advanced. Partner and Ref.'),
|
'Advanced. Partner and Ref.'),
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
##############################################################################
|
#
|
||||||
#
|
#
|
||||||
# Author: Leonardo Pistone
|
# Author: Leonardo Pistone
|
||||||
# Copyright 2014 Camptocamp SA
|
# Copyright 2014-2015 Camptocamp SA
|
||||||
#
|
#
|
||||||
# This program is free software: you can redistribute it and/or modify
|
# This program is free software: you can redistribute it and/or modify
|
||||||
# it under the terms of the GNU Affero General Public License as
|
# it under the terms of the GNU Affero General Public License as
|
||||||
@@ -17,32 +17,26 @@
|
|||||||
# You should have received a copy of the GNU Affero General Public License
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
##############################################################################
|
#
|
||||||
|
from openerp import models, fields, api
|
||||||
from openerp.osv import orm, fields
|
|
||||||
|
|
||||||
|
|
||||||
class AccountConfigSettings(orm.TransientModel):
|
class AccountConfigSettings(orm.TransientModel):
|
||||||
_inherit = 'account.config.settings'
|
_inherit = 'account.config.settings'
|
||||||
|
|
||||||
_columns = {
|
reconciliation_commit_every = fields.Integer(
|
||||||
'reconciliation_commit_every': fields.related(
|
related='company_id.reconciliation_commit_every',
|
||||||
'company_id',
|
string="How often to commit when performing automatic "
|
||||||
'reconciliation_commit_every',
|
"reconciliation.",
|
||||||
type='integer',
|
help="Leave zero to commit only at the end of the process.")
|
||||||
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']
|
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def onchange_company_id(self, company_id):
|
||||||
result = super(AccountConfigSettings, self).onchange_company_id(
|
result = super(AccountConfigSettings, self).onchange_company_id(
|
||||||
cr, uid, ids, company_id, context=None)
|
company_id)
|
||||||
|
|
||||||
if company_id:
|
if company_id:
|
||||||
company = company_obj.browse(cr, uid, company_id, context=context)
|
company = self.env['res.company'].browse(company_id)
|
||||||
result['value']['reconciliation_commit_every'] = (
|
result['value']['reconciliation_commit_every'] = (
|
||||||
company.reconciliation_commit_every
|
company.reconciliation_commit_every
|
||||||
)
|
)
|
||||||
@@ -51,9 +45,8 @@ class AccountConfigSettings(orm.TransientModel):
|
|||||||
|
|
||||||
class Company(orm.Model):
|
class Company(orm.Model):
|
||||||
_inherit = "res.company"
|
_inherit = "res.company"
|
||||||
_columns = {
|
|
||||||
'reconciliation_commit_every': fields.integer(
|
reconciliation_commit_every = fields.Integer(
|
||||||
string='How often to commit when performing automatic '
|
string="How often to commit when performing automatic "
|
||||||
'reconciliation.',
|
"reconciliation.",
|
||||||
help="""Leave zero to commit only at the end of the process."""),
|
help="Leave zero to commit only at the end of the process.")
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user