diff --git a/addons/account/__openerp__.py b/addons/account/__openerp__.py
index d4408d63bfe..39e40555f39 100644
--- a/addons/account/__openerp__.py
+++ b/addons/account/__openerp__.py
@@ -34,14 +34,15 @@
Budgets
Customer and Supplier Invoices
Bank statements
+ Reconciliation process by partner
Creates a dashboards for accountants that includes:
* List of uninvoiced quotations
* Graph of aged receivables
- * Graph of aged incomes
+ * Graph of aged incomes
The processes like maintaining of general ledger is done through the defined financial Journals (entry move line or
grouping is maintained through journal) for a particular financial year and for preparation of vouchers there is a
-module named account_voucherss
+module named account_vouchers
""",
'website': 'http://www.openerp.com',
'init_xml': [],
@@ -85,6 +86,7 @@ module named account_voucherss
'wizard/account_compare_account_balance_report_view.xml',
'wizard/account_third_party_ledger.xml',
'wizard/account_reconcile_view.xml',
+ 'wizard/account_reconcile_partner_process_view.xml',
'wizard/account_automatic_reconcile_view.xml',
'project/wizard/project_account_analytic_line_view.xml',
'account_end_fy.xml',
diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py
index 45edefe6082..72ab093e1ae 100644
--- a/addons/account/account_move_line.py
+++ b/addons/account/account_move_line.py
@@ -577,6 +577,39 @@ class account_move_line(osv.osv):
# writeoff; entry generated for the difference between the lines
#
+ def search(self, cr, uid, args, offset=0, limit=None, order=None, context=None, count=False):
+ if context is None:
+ 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)
+ else:
+ partner = context.get('partner_id', False)
+ if not partner:
+ return []
+ 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):
+ 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
+ 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)
+ 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)
+ ORDER BY p.last_reconciliation_date LIMIT 1 OFFSET %s""", (offset,)
+ )
+ return cr.fetchone()
+
def reconcile_partial(self, cr, uid, ids, type='auto', context=None):
merges = []
unmerge = []
@@ -730,6 +763,11 @@ class account_move_line(osv.osv):
# because of the way the line_id are defined: (4, x, False)
for id in ids:
wf_service.trg_trigger(uid, 'account.move.line', id, cr)
+
+ if lines and lines[0]:
+ partner_id = lines[0].partner_id.id
+ if context and context.get('stop_reconcile', False):
+ self.pool.get('res.partner').write(cr, uid, [partner_id], {'last_reconciliation_date': time.strftime('%Y-%m-%d %H:%M:%S')})
return r_id
def view_header_get(self, cr, user, view_id, view_type, context):
diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml
index 1787ba06927..a93179e3f98 100644
--- a/addons/account/account_view.xml
+++ b/addons/account/account_view.xml
@@ -842,7 +842,9 @@
-
+
+
+
@@ -1182,6 +1184,18 @@
id="menu_action_account_bank_reconcile_check_tree"
parent="periodical_processing_reconciliation" groups="group_account_user" />
+
+
+
+
-->
-
+
+
-
+
+
-
+
+ res.partner.form.reconcile
+ res.partner
+
+
+
+
+
+
+
+
diff --git a/addons/account/wizard/__init__.py b/addons/account/wizard/__init__.py
index 39971f5c11a..c56c6c2e764 100644
--- a/addons/account/wizard/__init__.py
+++ b/addons/account/wizard/__init__.py
@@ -22,6 +22,7 @@
import account_automatic_reconcile
import account_move_line_reconcile_select
import account_move_line_unreconcile_select
+import account_reconcile_partner_process
import account_reconcile
import account_unreconcile
import account_invoice_refund
diff --git a/addons/account/wizard/account_move_line_reconcile_select_view.xml b/addons/account/wizard/account_move_line_reconcile_select_view.xml
index 220c9e541de..4f88f618727 100644
--- a/addons/account/wizard/account_move_line_reconcile_select_view.xml
+++ b/addons/account/wizard/account_move_line_reconcile_select_view.xml
@@ -31,8 +31,8 @@
new
-
+
\ No newline at end of file
diff --git a/addons/account/wizard/account_move_line_unreconcile_select_view.xml b/addons/account/wizard/account_move_line_unreconcile_select_view.xml
index 1daae353725..f2a3882db91 100644
--- a/addons/account/wizard/account_move_line_unreconcile_select_view.xml
+++ b/addons/account/wizard/account_move_line_unreconcile_select_view.xml
@@ -31,8 +31,8 @@
new
-
+
\ No newline at end of file
diff --git a/addons/account/wizard/account_reconcile_partner_process.py b/addons/account/wizard/account_reconcile_partner_process.py
new file mode 100644
index 00000000000..6a1e354837d
--- /dev/null
+++ b/addons/account/wizard/account_reconcile_partner_process.py
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+##############################################################################
+#
+# OpenERP, Open Source Management Solution
+# Copyright (C) 2004-2010 Tiny SPRL ().
+#
+# 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 time
+
+from osv import osv, fields
+from tools.translate import _
+
+class account_partner_reconcile_process(osv.osv_memory):
+ _name = 'account.partner.reconcile.process'
+ _description = 'Reconcilation Process partner by partner'
+
+ def _get_to_reconcile(self, cr, uid, context=None):
+ cr.execute(
+ "SELECT l.partner_id " \
+ "FROM account_move_line AS l LEFT JOIN res_partner p ON (p.id = l.partner_id) " \
+ "WHERE l.reconcile_id IS NULL " \
+ "AND (%s > to_char(p.last_reconciliation_date, 'YYYY-MM-DD') " \
+ "OR p.last_reconciliation_date IS NULL ) " \
+ "AND l.state <> 'draft' " \
+ "GROUP BY l.partner_id ",(time.strftime('%Y-%m-%d'),)
+ )
+ return len(map(lambda x: x[0], cr.fetchall())) - 1
+
+ def _get_today_reconciled(self, cr, uid, context=None):
+ cr.execute(
+ "SELECT l.partner_id " \
+ "FROM account_move_line AS l LEFT JOIN res_partner p ON (p.id = l.partner_id) " \
+ "WHERE l.reconcile_id IS NULL " \
+ "AND %s = to_char(p.last_reconciliation_date, 'YYYY-MM-DD') " \
+ "AND l.state <> 'draft' " \
+ "GROUP BY l.partner_id ",(time.strftime('%Y-%m-%d'),)
+ )
+ return len(map(lambda x: x[0], cr.fetchall())) + 1
+
+ def _get_partner(self, cr, uid, context=None):
+ partner = self.pool.get('account.move.line').get_next_partner_only(cr, uid, offset=1, context=context)
+ if not partner:
+ return False
+ return partner[0]
+
+ def data_get(self, cr, uid, to_reconcile, today_reconciled, context=None):
+ return {'progress': (100 / float(to_reconcile + today_reconciled)) * today_reconciled}
+
+ def default_get(self, cr, uid, fields, context=None):
+ res = super(account_partner_reconcile_process, self).default_get(cr, uid, fields, context=context)
+ if 'to_reconcile' in res and 'today_reconciled' in res:
+ data = self.data_get(cr, uid, res['to_reconcile'], res['today_reconciled'], context)
+ res.update(data)
+ return res
+
+ def next_partner(self, cr, uid, ids, context=None):
+ partner_id = self.pool.get('account.move.line').read(cr, uid, context['active_id'], ['partner_id'])['partner_id'][0]
+ self.pool.get('res.partner').write(cr, uid, partner_id, {'last_reconciliation_date': time.strftime('%Y-%m-%d')}, context)
+ #TODO: we have to find a way to update the context of the current tab (we could open a new tab with the context but it's not really handy)
+ #TODO: remove that comments when the client side dev is done
+ #context.update({'partner_id': self.browse(cr, uid, ids, context)[0].next_partner_id})
+ #return {'context': context,
+ # 'target': 'opener',
+ # 'name': 'reconciliation process',
+ # 'view_type': 'form',
+ # 'view_mode': 'tree,form',
+ # 'res_model': 'account.move.line',
+ # 'type': 'ir.actions.act_window'
+ #}
+ return {}
+
+ _columns = {
+ 'to_reconcile': fields.float('Remaining Partners', readonly=True, help='This is the remaining partners for who you should check if there is something to reconcile or not. This figure already count the current partner as reconciled.'),
+ 'today_reconciled': fields.float('Partners Reconciled Today', readonly=True, help='This figure depicts the total number of partners that have gone throught the reconciliation process today. The current partner is counted as already processed.'),
+ 'progress': fields.float('Progress', readonly=True, help='Shows you the progress made today on the reconciliation process. Given by \nPartners Reconciled Today \ (Remaining Partners + Partners Reconciled Today)'),
+ 'next_partner_id': fields.many2one('res.partner', 'Next Partner to Reconcile', readonly=True, help='This field shows you the next partner that will be automatically chosen by the system to go through the reconciliation process, based on the latest day it have been reconciled.'), # TODO: remove the readonly=True when teh client side will allow to update the context of existing tab, so that the user can change this value if he doesn't want to follow openerp proposal
+ }
+
+ _defaults = {
+ 'to_reconcile': _get_to_reconcile,
+ 'today_reconciled': _get_today_reconciled,
+ 'next_partner_id': _get_partner,
+ }
+
+account_partner_reconcile_process()
+
+# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
diff --git a/addons/account/wizard/account_reconcile_partner_process_view.xml b/addons/account/wizard/account_reconcile_partner_process_view.xml
new file mode 100644
index 00000000000..cd296759752
--- /dev/null
+++ b/addons/account/wizard/account_reconcile_partner_process_view.xml
@@ -0,0 +1,54 @@
+
+
+
+
+
+
+ Account Partner Reconcile
+ account.partner.reconcile.process
+ form
+
+
+
+
+
+
+ Manual Reconciliation
+ account.partner.reconcile.process
+ ir.actions.act_window
+ form
+ tree,form
+
+ {'record_id':active_id}
+ new
+
+
+
+
+ Partner reconciliation
+ client_action_multi
+
+ action
+ account.move.line
+
+
+
+
+