From 8f134d5c85d694cb0271636cadb13ad6a9d90e13 Mon Sep 17 00:00:00 2001 From: "Quentin (OpenERP)" Date: Tue, 18 Sep 2012 14:46:40 +0200 Subject: [PATCH] [IMP/FIX] account, manual reconciliation process *replaced function get_next_partner() by list_partners_to_reconcile(), which is optmized, more explicit and returns now the result of name_get() (for convenience) *removed useless stuff about 'stop_reconcile' in context (replaced by the function has_something_to_reconcile()) *changed semantic of last_reconciliation_date field. It's now intented to be filled only when the given partner does not have anything remaining to reconcile) bzr revid: qdp-launchpad@openerp.com-20120918124640-eerh0ait8vt7n7ta --- addons/account/account_move_line.py | 32 ++++++++++--------- addons/account/partner.py | 27 ++++++++++++++-- addons/account/wizard/account_reconcile.py | 14 -------- .../account_reconcile_partner_process.py | 6 ++-- 4 files changed, 45 insertions(+), 34 deletions(-) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 18ab1a779a3..685e12becfa 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -703,7 +703,9 @@ class account_move_line(osv.osv): context = {} if context and context.get('next_partner_only', False): if not context.get('partner_id', False): - partner = self.get_next_partner_only(cr, uid, offset, context) + partner = self.list_partners_to_reconcile(cr, uid, context=context) + if partner: + partner = partner[0] else: partner = context.get('partner_id', False) if not partner: @@ -711,26 +713,26 @@ class account_move_line(osv.osv): args.append(('partner_id', '=', partner[0])) return super(account_move_line, self).search(cr, uid, args, offset, limit, order, context, count) - def get_next_partner_only(self, cr, uid, offset=0, context=None): + def list_partners_to_reconcile(self, cr, uid, context=None): cr.execute( """ - SELECT p.id - FROM res_partner p - RIGHT JOIN ( - SELECT l.partner_id AS partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit + SELECT partner_id + FROM ( + SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit FROM account_move_line l - LEFT JOIN account_account a ON (a.id = l.account_id) - LEFT JOIN res_partner p ON (l.partner_id = p.id) + RIGHT JOIN account_account a ON (a.id = l.account_id) + RIGHT JOIN res_partner p ON (l.partner_id = p.id) WHERE a.reconcile IS TRUE AND l.reconcile_id IS NULL AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date) AND l.state <> 'draft' - GROUP BY l.partner_id - ) AS s ON (p.id = s.partner_id) + GROUP BY l.partner_id, p.last_reconciliation_date + ) AS s WHERE debit > 0 AND credit > 0 - ORDER BY p.last_reconciliation_date LIMIT 1 OFFSET %s""", (offset, ) - ) - return cr.fetchone() + ORDER BY last_reconciliation_date""") + ids = cr.fetchall() + ids = len(ids) and list(ids[0]) or [] + return self.pool.get('res.partner').name_get(cr, uid, ids, context=context) def reconcile_partial(self, cr, uid, ids, type='auto', context=None, writeoff_acc_id=False, writeoff_period_id=False, writeoff_journal_id=False): move_rec_obj = self.pool.get('account.move.reconcile') @@ -910,8 +912,8 @@ class account_move_line(osv.osv): if lines and lines[0]: partner_id = lines[0].partner_id and lines[0].partner_id.id or False - if partner_id and context and context.get('stop_reconcile', False): - partner_obj.write(cr, uid, [partner_id], {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')}) + if not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context): + partner_obj.mark_as_reconciled(cr, uid, [partner_id], context=context) return r_id def view_header_get(self, cr, user, view_id, view_type, context=None): diff --git a/addons/account/partner.py b/addons/account/partner.py index 36fd88183f2..f2b9f79bb8a 100644 --- a/addons/account/partner.py +++ b/addons/account/partner.py @@ -20,8 +20,8 @@ ############################################################################## from operator import itemgetter - from osv import fields, osv +import time class account_fiscal_position(osv.osv): _name = 'account.fiscal.position' @@ -145,6 +145,29 @@ class res_partner(osv.osv): def _debit_search(self, cr, uid, obj, name, args, context=None): return self._asset_difference_search(cr, uid, obj, name, 'payable', args, context=context) + def has_something_to_reconcile(self, cr, uid, partner_id, context=None): + ''' + at least a debit, a credit and a line older than the last reconciliation date of the partner + ''' + cr.execute(''' + SELECT l.partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit + FROM account_move_line l + RIGHT JOIN account_account a ON (a.id = l.account_id) + RIGHT JOIN res_partner p ON (l.partner_id = p.id) + WHERE a.reconcile IS TRUE + AND p.id = %s + AND l.reconcile_id IS NULL + AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date) + AND l.state <> 'draft' + GROUP BY l.partner_id''', (partner_id,)) + res = cr.dictfetchone() + if res: + return bool(res['debit'] and res['credit']) + return False + + def mark_as_reconciled(self, cr, uid, ids, context=None): + return self.write(cr, uid, ids, {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')}, context=context) + _columns = { 'credit': fields.function(_credit_debit_get, fnct_search=_credit_search, string='Total Receivable', multi='dc', help="Total amount this customer owes you."), @@ -185,7 +208,7 @@ class res_partner(osv.osv): help="This payment term will be used instead of the default one for the current partner"), 'ref_companies': fields.one2many('res.company', 'partner_id', 'Companies that refers to partner'), - 'last_reconciliation_date': fields.datetime('Latest Reconciliation Date', help='Date on which the partner accounting entries were reconciled last time') + 'last_reconciliation_date': fields.datetime('Latest Reconciliation Date', help='Date on which the partner accounting entries were fully reconciled last time. It differs from the date of the last reconciliation made for this partner, as here we depict the fact that nothing more was to be reconciled at this date. This can be achieved in 2 ways: either the last debit/credit entry was reconciled, either the user pressed the button "Fully Reconciled" in the manual reconciliation process') } res_partner() diff --git a/addons/account/wizard/account_reconcile.py b/addons/account/wizard/account_reconcile.py index 729792e2222..9fa521c09f7 100644 --- a/addons/account/wizard/account_reconcile.py +++ b/addons/account/wizard/account_reconcile.py @@ -86,19 +86,6 @@ class account_move_line_reconcile(osv.osv_memory): ids = period_obj.find(cr, uid, dt=date, context=context) if ids: period_id = ids[0] - #stop the reconciliation process by partner (manual reconciliation) only if there is nothing more to reconcile for this partner - if 'active_ids' in context and context['active_ids']: - tmp_ml_id = account_move_line_obj.browse(cr, uid, context['active_ids'], context)[0] - partner_id = tmp_ml_id.partner_id and tmp_ml_id.partner_id.id or False - debit_ml_ids = account_move_line_obj.search(cr, uid, [('partner_id', '=', partner_id), ('account_id.reconcile', '=', True), ('reconcile_id', '=', False), ('debit', '>', 0)], context=context) - credit_ml_ids = account_move_line_obj.search(cr, uid, [('partner_id', '=', partner_id), ('account_id.reconcile', '=', True), ('reconcile_id', '=', False), ('credit', '>', 0)], context=context) - for ml_id in context['active_ids']: - if ml_id in debit_ml_ids: - debit_ml_ids.remove(ml_id) - if ml_id in credit_ml_ids: - credit_ml_ids.remove(ml_id) - if not debit_ml_ids and credit_ml_ids: - context.update({'stop_reconcile': True}) account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id, period_id, journal_id, context=context) return {'type': 'ir.actions.act_window_close'} @@ -166,7 +153,6 @@ class account_move_line_reconcile_writeoff(osv.osv_memory): if ids: period_id = ids[0] - context.update({'stop_reconcile': True}) account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id, period_id, journal_id, context=context) return {'type': 'ir.actions.act_window_close'} diff --git a/addons/account/wizard/account_reconcile_partner_process.py b/addons/account/wizard/account_reconcile_partner_process.py index 7cfeff70891..380d25001c7 100644 --- a/addons/account/wizard/account_reconcile_partner_process.py +++ b/addons/account/wizard/account_reconcile_partner_process.py @@ -57,10 +57,10 @@ class account_partner_reconcile_process(osv.osv_memory): def _get_partner(self, cr, uid, context=None): move_line_obj = self.pool.get('account.move.line') - partner = move_line_obj.get_next_partner_only(cr, uid, offset=1, context=context) + partner = move_line_obj.list_partners_to_reconcile(cr, uid, context=context) if not partner: return False - return partner[0] + return partner[0][0] def data_get(self, cr, uid, to_reconcile, today_reconciled, context=None): return {'progress': (100 / (float(to_reconcile + today_reconciled) or 1.0)) * today_reconciled} @@ -100,4 +100,4 @@ class account_partner_reconcile_process(osv.osv_memory): account_partner_reconcile_process() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: