[REF] account: refactoring of aged partner balance report in order to have that query reusable for the enterprise report
This commit is contained in:
@@ -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] = {'<partner_id>': <partner_debit-credit>}
|
||||
@@ -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)
|
||||
|
||||
@@ -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"/>
|
||||
<act_window
|
||||
id="act_account_partner_ledger_payable_no_partner"
|
||||
name="Unknown Partner Ledger"
|
||||
res_model="account.move.line"
|
||||
context="{'search_default_unreconciled':1, 'search_default_payable':1}"
|
||||
domain="[('partner_id', '=', False)]"
|
||||
src_model="res.partner"/>
|
||||
|
||||
<act_window
|
||||
id="act_account_partner_ledger_receivable"
|
||||
@@ -149,6 +156,14 @@
|
||||
res_model="account.move.line"
|
||||
context="{'search_default_partner_id':[active_id], 'search_default_unreconciled':1, 'search_default_receivable':1}"
|
||||
src_model="res.partner"/>
|
||||
<act_window
|
||||
id="act_account_partner_ledger_receivable_no_partner"
|
||||
name="Unknown Partner Ledger"
|
||||
res_model="account.move.line"
|
||||
context="{'search_default_unreconciled':1, 'search_default_receivable':1}"
|
||||
domain="[('partner_id', '=', False)]"
|
||||
src_model="res.partner"/>
|
||||
|
||||
|
||||
<act_window
|
||||
id="act_account_acount_move_line_open_unreconciled"
|
||||
|
||||
Reference in New Issue
Block a user