diff --git a/account_easy_reconcile/easy_reconcile.py b/account_easy_reconcile/easy_reconcile.py index 1d348e68..16b3cae8 100644 --- a/account_easy_reconcile/easy_reconcile.py +++ b/account_easy_reconcile/easy_reconcile.py @@ -17,10 +17,11 @@ #along with this program. If not, see . # ######################################################################### -from osv import fields,osv -from tools.translate import _ import time import string +from osv import fields, osv +from tools.translate import _ +from tools import DEFAULT_SERVER_DATETIME_FORMAT class account_easy_reconcile_method(osv.osv): @@ -30,16 +31,16 @@ class account_easy_reconcile_method(osv.osv): def onchange_name(self, cr, uid, id, name, write_off, context=None): if name in ['action_rec_auto_name', 'action_rec_auto_partner']: if write_off>0: - return {'value' : {'require_write_off' : True, 'require_account_id' : True, 'require_journal_id' : True}} - return {'value' : {'require_write_off' : True}} + return {'value': {'require_write_off': True, 'require_account_id': True, 'require_journal_id': True}} + return {'value': {'require_write_off': True}} return {} def onchange_write_off(self, cr, uid, id, name, write_off, context=None): if name in ['action_rec_auto_name', 'action_rec_auto_partner']: if write_off>0: - return {'value' : {'require_account_id' : True, 'require_journal_id' : True}} + return {'value': {'require_account_id': True, 'require_journal_id': True}} else: - return {'value' : {'require_account_id' : False, 'require_journal_id' : False}} + return {'value': {'require_account_id': False, 'require_journal_id': False}} return {} def _get_all_rec_method(self, cr, uid, context=None): @@ -58,11 +59,11 @@ class account_easy_reconcile_method(osv.osv): 'account_lost_id': fields.many2one('account.account', 'Account Lost'), 'account_profit_id': fields.many2one('account.account', 'Account Profit'), 'journal_id': fields.many2one('account.journal', 'Journal'), - 'require_write_off' : fields.boolean('Require Write-off'), - 'require_account_id' : fields.boolean('Require Account'), - 'require_journal_id' : fields.boolean('Require Journal'), + 'require_write_off': fields.boolean('Require Write-off'), + 'require_account_id': fields.boolean('Require Account'), + 'require_journal_id': fields.boolean('Require Journal'), 'date_base_on': fields.selection([('newest', 'the most recent'), ('actual', 'today'), ('credit_line', 'credit line date'), ('debit_line', 'debit line date')], 'Date Base On'), - 'filter' : fields.char('Filter', size=128), + 'filter': fields.char('Filter', size=128), } _defaults = { @@ -97,108 +98,122 @@ class account_easy_reconcile(osv.osv): def rec_auto_lines_simple(self, cr, uid, lines, context=None): if not context: context={} - count=0 - res=0 - max = context.get('write_off', 0) + 0.001 - while (count 0 and lines[i][2] > 0: + if lines[count]['credit'] > 0 and lines[i]['debit'] > 0: credit_line = lines[count] debit_line = lines[i] - check =True - elif lines[i][1] > 0 and lines[count][2] > 0: + check = True + elif lines[i]['credit'] > 0 and lines[count]['debit'] > 0: credit_line = lines[i] debit_line = lines[count] - check=True + check = True + if not check: + continue - if check and abs(credit_line[1] - debit_line[2]) <= max: - if context.get('write_off', 0) > 0 and abs(credit_line[1] - debit_line[2]) > 0.001: - if credit_line[1] < debit_line[2]: - writeoff_account_id = context.get('account_profit_id',False) + diff = round(abs(credit_line['credit'] - debit_line['debit']), precision) + if diff <= max_diff: + if context.get('write_off', 0) > 0 and diff: + if credit_line['credit'] < debit_line['debit']: + writeoff_account_id = context.get('account_profit_id', False) else: - writeoff_account_id = context.get('account_lost_id',False) + writeoff_account_id = context.get('account_lost_id', False) - #context['date_base_on'] = 'credit_line' - context['comment'] = _('Write-Off %s')%credit_line[0] + context['comment'] = _('Write-Off %s') % credit_line['key'] - if context.get('date_base_on', False) == 'credit_line': - date = credit_line[4] - elif context.get('date_base_on', False) == 'debit_line': - date = debit_line[4] - elif context.get('date_base_on', False) == 'newest': - date = (credit_line[4] > debit_line[4]) and credit_line[4] or debit_line[4] + if context.get('date_base_on') == 'credit_line': + date = credit_line['date'] + elif context.get('date_base_on') == 'debit_line': + date = debit_line['date'] + elif context.get('date_base_on') == 'newest': + date = (credit_line['date'] > debit_line['date']) and credit_line['date'] or debit_line['date'] else: date = None context['date_p'] = date period_id = self.pool.get('account.period').find(cr, uid, dt=date, context=context)[0] - self.pool.get('account.move.line').reconcile(cr, uid, [lines[count][3], lines[i][3]], writeoff_acc_id=writeoff_account_id, writeoff_period_id=period_id, writeoff_journal_id=context.get('journal_id'), context=context) + self.pool.get('account.move.line').reconcile(cr, uid, [lines[count]['id'], lines[i]['id']], writeoff_acc_id=writeoff_account_id, writeoff_period_id=period_id, writeoff_journal_id=context.get('journal_id'), context=context) del lines[i] - res+=2 + res += 2 break - count+=1 + count += 1 return res def get_params(self, cr, uid, account_id, context): if context.get('filter'): (from_clause, where_clause, where_clause_params) = self.pool.get('account.move.line')._where_calc(cr, uid, context['filter'], context=context).get_sql() if where_clause: - where_clause = " AND %s"%where_clause - where_clause_params = (account_id,) + tuple(where_clause_params) + where_clause = " AND %s" % where_clause + where_clause_params = account_id, + tuple(where_clause_params) else: - print 'id', account_id where_clause = '' - where_clause_params = (account_id,) + where_clause_params = account_id, return where_clause, where_clause_params def action_rec_auto_name(self, cr, uid, account_id, context): (qu1, qu2) = self.get_params(cr, uid, account_id, context) cr.execute(""" - SELECT name, credit, debit, id, date + SELECT name as key, credit, debit, id, date FROM account_move_line WHERE account_id=%s AND reconcile_id IS NULL AND name IS NOT NULL""" + qu1 + " ORDER BY name", qu2) - lines = cr.fetchall() + lines = cr.dictfetchall() return self.rec_auto_lines_simple(cr, uid, lines, context) def action_rec_auto_partner(self, cr, uid, account_id, context): (qu1, qu2) = self.get_params(cr, uid, account_id, context) cr.execute(""" - SELECT partner_id, credit, debit, id, date + SELECT partner_id as key, credit, debit, id, date FROM account_move_line WHERE account_id=%s AND reconcile_id IS NULL AND partner_id IS NOT NULL""" + qu1 + " ORDER BY partner_id", qu2) - lines = cr.fetchall() + lines = cr.dictfetchall() return self.rec_auto_lines_simple(cr, uid, lines, context) def action_rec_auto(self, cr, uid, ids, context=None): - if not context: - context={} - for id in ids: - easy_rec = self.browse(cr, uid, id, context) - total_rec=0 + if context is None: + context = {} + for rec_id in ids: + rec = self.browse(cr, uid, rec_id, context=context) + total_rec = 0 details = '' count = 0 - for method in easy_rec.reconcile_method: + for method in rec.reconcile_method: count += 1 - context.update({'date_base_on' : method.date_base_on, 'filter' : eval(method.filter or '[]'), 'write_off': (method.write_off>0 and method.write_off) or 0, 'account_lost_id':method.account_lost_id.id, 'account_profit_id':method.account_profit_id.id, 'journal_id':method.journal_id.id}) - res = eval('self.'+ str(method.name) +'(cr, uid, ' + str(easy_rec.account.id) +', context)') - details += _(' method ') + str(count) + ' : ' + str(res) + _(' lines') +' |' - log = self.read(cr, uid, id, ['rec_log'], context=context)['rec_log'] - log_line = log and log.split("\n") or [] - log_line[0:0] = [time.strftime('%Y-%m-%d %H:%M:%S') + ' : ' + str(total_rec) + _(' lines have been reconciled ('+ details[0:-2] + ')')] - log = "\n".join(log_line) - self.write(cr, uid, id, {'rec_log' : log}, context=context) + ctx = dict( + context, + date_base_on=method.date_base_on, + filter=eval(method.filter or '[]'), + write_off=(method.write_off > 0 and method.write_off) or 0, + account_lost_id=method.account_lost_id.id, + account_profit_id=method.account_profit_id.id, + journal_id=method.journal_id.id) + + py_meth = getattr(self, method.name) + res = py_meth(cr, uid, rec.account.id, context=context) + details += _(' method %d : %d lines |') % (count, res) + log = self.read(cr, uid, rec_id, ['rec_log'], context=context)['rec_log'] + log_lines = log and log.splitlines or [] + log_lines[0:0] = [_('%s : %d lines have been reconciled (%s)') % + (time.strftime(DEFAULT_SERVER_DATETIME_FORMAT), total_rec, details[0:-2])] + log = "\n".join(log_lines) + self.write(cr, uid, rec_id, {'rec_log': log}, context=context) return True account_easy_reconcile() @@ -209,7 +224,7 @@ class account_easy_reconcile_method(osv.osv): _inherit = 'account.easy.reconcile.method' _columns = { - 'task_id' : fields.many2one('account.easy.reconcile', 'Task', required=True, ondelete='cascade'), + 'task_id': fields.many2one('account.easy.reconcile', 'Task', required=True, ondelete='cascade'), } account_easy_reconcile_method()