[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
This commit is contained in:
Quentin (OpenERP) 2012-09-18 14:46:40 +02:00
parent 4de5eb2c96
commit 8f134d5c85
4 changed files with 45 additions and 34 deletions

View File

@ -703,7 +703,9 @@ class account_move_line(osv.osv):
context = {} context = {}
if context and context.get('next_partner_only', False): if context and context.get('next_partner_only', False):
if not context.get('partner_id', 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: else:
partner = context.get('partner_id', False) partner = context.get('partner_id', False)
if not partner: if not partner:
@ -711,26 +713,26 @@ class account_move_line(osv.osv):
args.append(('partner_id', '=', partner[0])) args.append(('partner_id', '=', partner[0]))
return super(account_move_line, self).search(cr, uid, args, offset, limit, order, context, count) 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( cr.execute(
""" """
SELECT p.id SELECT partner_id
FROM res_partner p FROM (
RIGHT JOIN ( SELECT l.partner_id, p.last_reconciliation_date, SUM(l.debit) AS debit, SUM(l.credit) AS credit
SELECT l.partner_id AS partner_id, SUM(l.debit) AS debit, SUM(l.credit) AS credit
FROM account_move_line l FROM account_move_line l
LEFT JOIN account_account a ON (a.id = l.account_id) RIGHT JOIN account_account a ON (a.id = l.account_id)
LEFT JOIN res_partner p ON (l.partner_id = p.id) RIGHT JOIN res_partner p ON (l.partner_id = p.id)
WHERE a.reconcile IS TRUE WHERE a.reconcile IS TRUE
AND l.reconcile_id IS NULL AND l.reconcile_id IS NULL
AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date) AND (p.last_reconciliation_date IS NULL OR l.date > p.last_reconciliation_date)
AND l.state <> 'draft' AND l.state <> 'draft'
GROUP BY l.partner_id GROUP BY l.partner_id, p.last_reconciliation_date
) AS s ON (p.id = s.partner_id) ) AS s
WHERE debit > 0 AND credit > 0 WHERE debit > 0 AND credit > 0
ORDER BY p.last_reconciliation_date LIMIT 1 OFFSET %s""", (offset, ) ORDER BY last_reconciliation_date""")
) ids = cr.fetchall()
return cr.fetchone() 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): 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') move_rec_obj = self.pool.get('account.move.reconcile')
@ -910,8 +912,8 @@ class account_move_line(osv.osv):
if lines and lines[0]: if lines and lines[0]:
partner_id = lines[0].partner_id and lines[0].partner_id.id or False 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): if not partner_obj.has_something_to_reconcile(cr, uid, partner_id, context=context):
partner_obj.write(cr, uid, [partner_id], {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')}) partner_obj.mark_as_reconciled(cr, uid, [partner_id], context=context)
return r_id return r_id
def view_header_get(self, cr, user, view_id, view_type, context=None): def view_header_get(self, cr, user, view_id, view_type, context=None):

View File

@ -20,8 +20,8 @@
############################################################################## ##############################################################################
from operator import itemgetter from operator import itemgetter
from osv import fields, osv from osv import fields, osv
import time
class account_fiscal_position(osv.osv): class account_fiscal_position(osv.osv):
_name = 'account.fiscal.position' _name = 'account.fiscal.position'
@ -145,6 +145,29 @@ class res_partner(osv.osv):
def _debit_search(self, cr, uid, obj, name, args, context=None): def _debit_search(self, cr, uid, obj, name, args, context=None):
return self._asset_difference_search(cr, uid, obj, name, 'payable', args, context=context) 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 = { _columns = {
'credit': fields.function(_credit_debit_get, 'credit': fields.function(_credit_debit_get,
fnct_search=_credit_search, string='Total Receivable', multi='dc', help="Total amount this customer owes you."), 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"), help="This payment term will be used instead of the default one for the current partner"),
'ref_companies': fields.one2many('res.company', 'partner_id', 'ref_companies': fields.one2many('res.company', 'partner_id',
'Companies that refers to partner'), '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() res_partner()

View File

@ -86,19 +86,6 @@ class account_move_line_reconcile(osv.osv_memory):
ids = period_obj.find(cr, uid, dt=date, context=context) ids = period_obj.find(cr, uid, dt=date, context=context)
if ids: if ids:
period_id = ids[0] 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, account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id,
period_id, journal_id, context=context) period_id, journal_id, context=context)
return {'type': 'ir.actions.act_window_close'} return {'type': 'ir.actions.act_window_close'}
@ -166,7 +153,6 @@ class account_move_line_reconcile_writeoff(osv.osv_memory):
if ids: if ids:
period_id = ids[0] period_id = ids[0]
context.update({'stop_reconcile': True})
account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id, account_move_line_obj.reconcile(cr, uid, context['active_ids'], 'manual', account_id,
period_id, journal_id, context=context) period_id, journal_id, context=context)
return {'type': 'ir.actions.act_window_close'} return {'type': 'ir.actions.act_window_close'}

View File

@ -57,10 +57,10 @@ class account_partner_reconcile_process(osv.osv_memory):
def _get_partner(self, cr, uid, context=None): def _get_partner(self, cr, uid, context=None):
move_line_obj = self.pool.get('account.move.line') 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: if not partner:
return False return False
return partner[0] return partner[0][0]
def data_get(self, cr, uid, to_reconcile, today_reconciled, context=None): 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} 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() account_partner_reconcile_process()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: