diff --git a/addons/account/report/account_aged_partner_balance.py b/addons/account/report/account_aged_partner_balance.py index 7bcb8432926..9743366d950 100644 --- a/addons/account/report/account_aged_partner_balance.py +++ b/addons/account/report/account_aged_partner_balance.py @@ -3,15 +3,28 @@ import time from openerp import api, models, _ from openerp.tools import float_is_zero +from datetime import datetime +from dateutil.relativedelta import relativedelta class ReportAgedPartnerBalance(models.AbstractModel): _name = 'report.account.report_agedpartnerbalance' - def _get_partner_move_lines(self, form, account_type, date_from, target_move): + def _get_partner_move_lines(self, account_type, date_from, target_move, period_length): + periods = {} + start = datetime.strptime(date_from, "%Y-%m-%d") + for i in range(5)[::-1]: + stop = start - relativedelta(days=period_length) + periods[str(i)] = { + 'name': (i!=0 and (str((5-(i+1)) * period_length) + '-' + str((5-i) * period_length)) or ('+'+str(4 * period_length))), + 'stop': start.strftime('%Y-%m-%d'), + 'start': (i!=0 and stop.strftime('%Y-%m-%d') or False), + } + start = stop - relativedelta(days=1) + res = [] - self.total_account = [] + total = [] cr = self.env.cr user_company = self.env.user.company_id.id move_state = ['draft', 'posted'] @@ -29,14 +42,13 @@ class ReportAgedPartnerBalance(models.AbstractModel): arg_list += (tuple(reconciled_after_date),) arg_list += (date_from, user_company) query = ''' - SELECT DISTINCT res_partner.id AS id, res_partner.name AS name, UPPER(res_partner.name) AS uppername - FROM res_partner,account_move_line AS l, account_account, account_move am + SELECT DISTINCT l.partner_id, UPPER(res_partner.name) + FROM account_move_line AS l left join res_partner on l.partner_id = res_partner.id, account_account, account_move am WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) AND (am.state IN %s) AND (account_account.internal_type IN %s) AND ''' + reconciliation_clause + ''' - AND (l.partner_id = res_partner.id) AND (l.date <= %s) AND l.company_id = %s ORDER BY UPPER(res_partner.name)''' @@ -45,30 +57,31 @@ class ReportAgedPartnerBalance(models.AbstractModel): partners = cr.dictfetchall() # put a total of 0 for i in range(7): - self.total_account.append(0) + total.append(0) # Build a string like (1,2,3) for easy use in SQL query - partner_ids = [partner['id'] for partner in partners] + partner_ids = [partner['partner_id'] for partner in partners if partner['partner_id']] if not partner_ids: - return [] + return [], [] # This dictionary will store the not due amount of all partners - future_past = {} + undue_amounts = {} query = '''SELECT l.id FROM account_move_line AS l, account_account, account_move am WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) AND (am.state IN %s) AND (account_account.internal_type IN %s) AND (COALESCE(l.date_maturity,l.date) > %s)\ - AND (l.partner_id IN %s) + AND ((l.partner_id IN %s) OR (l.partner_id IS NULL)) AND (l.date <= %s) AND l.company_id = %s''' cr.execute(query, (tuple(move_state), tuple(account_type), date_from, tuple(partner_ids), date_from, user_company)) aml_ids = cr.fetchall() aml_ids = aml_ids and [x[0] for x in aml_ids] or [] for line in self.env['account.move.line'].browse(aml_ids): - if line.partner_id.id not in future_past: - future_past[line.partner_id.id] = 0.0 + partner_id = line.partner_id.id or None + if partner_id not in undue_amounts: + undue_amounts[partner_id] = 0.0 line_amount = line.balance if line.balance == 0: continue @@ -78,7 +91,7 @@ class ReportAgedPartnerBalance(models.AbstractModel): for partial_line in line.matched_credit_ids: if partial_line.create_date[:10] <= date_from: line_amount -= partial_line.amount - future_past[line.partner_id.id] += line_amount + undue_amounts[partner_id] += line_amount # Use one query per period and store results in history (a list variable) # Each history will contain: history[1] = {'': } @@ -87,15 +100,15 @@ class ReportAgedPartnerBalance(models.AbstractModel): args_list = (tuple(move_state), tuple(account_type), tuple(partner_ids),) dates_query = '(COALESCE(l.date_maturity,l.date)' - if form[str(i)]['start'] and form[str(i)]['stop']: + if periods[str(i)]['start'] and periods[str(i)]['stop']: dates_query += ' BETWEEN %s AND %s)' - args_list += (form[str(i)]['start'], form[str(i)]['stop']) - elif form[str(i)]['start']: + args_list += (periods[str(i)]['start'], periods[str(i)]['stop']) + elif periods[str(i)]['start']: dates_query += ' >= %s)' - args_list += (form[str(i)]['start'],) + args_list += (periods[str(i)]['start'],) else: dates_query += ' <= %s)' - args_list += (form[str(i)]['stop'],) + args_list += (periods[str(i)]['stop'],) args_list += (date_from, user_company) query = '''SELECT l.id @@ -103,7 +116,7 @@ class ReportAgedPartnerBalance(models.AbstractModel): WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) AND (am.state IN %s) AND (account_account.internal_type IN %s) - AND (l.partner_id IN %s) + AND ((l.partner_id IN %s) OR (l.partner_id IS NULL)) AND ''' + dates_query + ''' AND (l.date <= %s) AND l.company_id = %s''' @@ -112,8 +125,9 @@ class ReportAgedPartnerBalance(models.AbstractModel): aml_ids = cr.fetchall() aml_ids = aml_ids and [x[0] for x in aml_ids] or [] for line in self.env['account.move.line'].browse(aml_ids): - if line.partner_id.id not in partners_amount: - partners_amount[line.partner_id.id] = 0.0 + partner_id = line.partner_id.id or None + if partner_id not in partners_amount: + partners_amount[partner_id] = 0.0 line_amount = line.balance if line.balance == 0: continue @@ -124,159 +138,50 @@ class ReportAgedPartnerBalance(models.AbstractModel): if partial_line.create_date[:10] <= date_from: line_amount -= partial_line.amount - partners_amount[line.partner_id.id] += line_amount + partners_amount[partner_id] += line_amount history.append(partners_amount) for partner in partners: + at_least_one_amount = False values = {} - # Query here is replaced by one query which gets the all the partners their 'after' value - after = False - if partner['id'] in future_past: # Making sure this partner actually was found by the query - after = [future_past[partner['id']]] + undue_amt = 0.0 + if partner['partner_id'] in undue_amounts: # Making sure this partner actually was found by the query + undue_amt = undue_amounts[partner['partner_id']] - self.total_account[6] = self.total_account[6] + (after and after[0] or 0.0) - values['direction'] = after and after[0] or 0.0 + total[6] = total[6] + undue_amt + values['direction'] = undue_amt if not float_is_zero(values['direction'], precision_rounding=self.env.user.company_id.currency_id.rounding): at_least_one_amount = True for i in range(5): during = False - if partner['id'] in history[i]: - during = [history[i][partner['id']]] + if partner['partner_id'] in history[i]: + during = [history[i][partner['partner_id']]] # Adding counter - self.total_account[(i)] = self.total_account[(i)] + (during and during[0] or 0) + total[(i)] = total[(i)] + (during and during[0] or 0) values[str(i)] = during and during[0] or 0.0 if not float_is_zero(values[str(i)], precision_rounding=self.env.user.company_id.currency_id.rounding): at_least_one_amount = True values['total'] = sum([values['direction']] + [values[str(i)] for i in range(5)]) ## Add for total - self.total_account[(i + 1)] += values['total'] - values['name'] = partner['name'] + total[(i + 1)] += values['total'] + values['partner_id'] = partner['partner_id'] + if partner['partner_id']: + browsed_partner = self.env['res.partner'].browse(partner['partner_id']) + values['name'] = browsed_partner.name and len(browsed_partner.name) >= 45 and browsed_partner.name[0:40] + '...' or browsed_partner.name + values['trust'] = browsed_partner.trust + else: + values['name'] = _('Unknown Partner') + values['trust'] = False if at_least_one_amount: res.append(values) - total = 0.0 - totals = {} - for r in res: - total += float(r['total'] or 0.0) - for i in range(5) + ['direction']: - totals.setdefault(str(i), 0.0) - totals[str(i)] += float(r[str(i)] or 0.0) - return res - - def _get_move_lines_with_out_partner(self, form, account_type, date_from, target_move): - res = [] - cr = self.env.cr - move_state = ['draft', 'posted'] - if target_move == 'posted': - move_state = ['posted'] - - user_company = self.env.user.company_id.id - ## put a total of 0 - for i in range(7): - self.total_account.append(0) - - # This dictionary will store the not due amount of the unknown partner - future_past = {'Unknown Partner': 0} - query = '''SELECT l.id - FROM account_move_line AS l, account_account, account_move am - WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) - AND (am.state IN %s) - AND (account_account.internal_type IN %s) - AND (COALESCE(l.date_maturity,l.date) > %s)\ - AND (l.partner_id IS NULL) - AND (l.date <= %s) - AND l.company_id = %s''' - cr.execute(query, (tuple(move_state), tuple(account_type), date_from, date_from, user_company)) - aml_ids = cr.fetchall() - aml_ids = aml_ids and [x[0] for x in aml_ids] or [] - for line in self.env['account.move.line'].browse(aml_ids): - line_amount = line.balance - if line.balance == 0: - continue - for partial_line in line.matched_debit_ids: - if partial_line.create_date[:10] <= date_from: - line_amount += partial_line.amount - for partial_line in line.matched_credit_ids: - if partial_line.create_date[:10] <= date_from: - line_amount -= partial_line.amount - future_past['Unknown Partner'] += line_amount - - history = [] - for i in range(5): - args_list = (tuple(move_state), tuple(account_type)) - dates_query = '(COALESCE(l.date_maturity,l.date)' - if form[str(i)]['start'] and form[str(i)]['stop']: - dates_query += ' BETWEEN %s AND %s)' - args_list += (form[str(i)]['start'], form[str(i)]['stop']) - elif form[str(i)]['start']: - dates_query += ' > %s)' - args_list += (form[str(i)]['start'],) - else: - dates_query += ' < %s)' - args_list += (form[str(i)]['stop'],) - args_list += (date_from, user_company) - query = '''SELECT l.id - FROM account_move_line AS l, account_account, account_move am - WHERE (l.account_id = account_account.id) AND (l.move_id = am.id) - AND (am.state IN %s) - AND (account_account.internal_type IN %s) - AND (l.partner_id IS NULL) - AND ''' + dates_query + ''' - AND (l.date <= %s) - AND l.company_id = %s''' - cr.execute(query, args_list) - history_data = {'Unknown Partner': 0} - aml_ids = cr.fetchall() - aml_ids = aml_ids and [x[0] for x in aml_ids] or [] - for line in self.env['account.move.line'].browse(aml_ids): - line_amount = line.balance - if line.balance == 0: - continue - for partial_line in line.matched_debit_ids: - if partial_line.create_date[:10] <= date_from: - line_amount += partial_line.amount - for partial_line in line.matched_credit_ids: - if partial_line.create_date[:10] <= date_from: - line_amount -= partial_line.amount - history_data['Unknown Partner'] += line_amount - history.append(history_data) - - values = {} - after = False - if 'Unknown Partner' in future_past: - after = [future_past['Unknown Partner']] - self.total_account[6] = self.total_account[6] + (after and after[0] or 0.0) - values['direction'] = after and after[0] or 0.0 - - for i in range(5): - during = False - if 'Unknown Partner' in history[i]: - during = [history[i]['Unknown Partner']] - self.total_account[(i)] = self.total_account[(i)] + (during and during[0] or 0) - values[str(i)] = during and during[0] or 0.0 - - values['total'] = sum([values['direction']] + [values[str(i)] for i in range(5)]) - ## Add for total - self.total_account[(i + 1)] += values['total'] - values['name'] = _('Unknown Partner') - - if values['total']: - res.append(values) - - total = 0.0 - totals = {} - for r in res: - total += float(r['total'] or 0.0) - for i in range(5) + ['direction']: - totals.setdefault(str(i), 0.0) - totals[str(i)] += float(r[str(i)] or 0.0) - return res + return res, total @api.multi def render_html(self, data): - self.total_account = [] + total = [] model = self.env.context.get('active_model') docs = self.env[model].browse(self.env.context.get('active_id')) @@ -288,14 +193,9 @@ class ReportAgedPartnerBalance(models.AbstractModel): elif data['form']['result_selection'] == 'supplier': account_type = ['payable'] else: - account_type = ['payable','receivable'] + account_type = ['payable', 'receivable'] - without_partner_movelines = self._get_move_lines_with_out_partner(data['form'], account_type, date_from, target_move) - tot_list = self.total_account - partner_movelines = self._get_partner_move_lines(data['form'], account_type, date_from, target_move) - for i in range(7): - self.total_account[i] += tot_list[i] - movelines = partner_movelines + without_partner_movelines + movelines, total = self._get_partner_move_lines(account_type, date_from, target_move, data['form']['period_length']) docargs = { 'doc_ids': self.ids, 'doc_model': model, @@ -303,6 +203,6 @@ class ReportAgedPartnerBalance(models.AbstractModel): 'docs': docs, 'time': time, 'get_partner_lines': movelines, - 'get_direction': self.total_account, + 'get_direction': total, } return self.env['report'].render('account.report_agedpartnerbalance', docargs) diff --git a/addons/account/views/account_view.xml b/addons/account/views/account_view.xml index 778ae1a71e0..08be467b7e7 100644 --- a/addons/account/views/account_view.xml +++ b/addons/account/views/account_view.xml @@ -142,6 +142,13 @@ res_model="account.move.line" context="{'search_default_partner_id':[active_id], 'search_default_unreconciled':1, 'search_default_payable':1}" src_model="res.partner"/> + + +