[IMP] account: Cleanup remaining stuff of Aged Partner Balance
This report is only available in enterprise edition. This report is now entirely moved in account_reports. This report is no longer available in community since: https://github.com/odoo/odoo/commit/e51b4f659fc5e4253d3156754ada21166c8d1bf8 closes odoo/odoo#38502 Signed-off-by: Quentin De Paoli (qdp) <qdp@openerp.com>
This commit is contained in:
@@ -3,5 +3,4 @@
|
||||
|
||||
from . import account_invoice_report
|
||||
from . import account_journal
|
||||
from . import account_aged_partner_balance
|
||||
from . import account_hash_integrity_templates
|
||||
|
||||
@@ -1,262 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import time
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError
|
||||
from odoo.tools import float_is_zero
|
||||
from datetime import datetime
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
class ReportAgedPartnerBalance(models.AbstractModel):
|
||||
|
||||
_name = 'report.account.report_agedpartnerbalance'
|
||||
_description = 'Aged Partner Balance Report'
|
||||
|
||||
def _get_partner_move_lines(self, account_type, date_from, target_move, period_length):
|
||||
# This method can receive the context key 'include_nullified_amount' {Boolean}
|
||||
# Do an invoice and a payment and unreconcile. The amount will be nullified
|
||||
# By default, the partner wouldn't appear in this report.
|
||||
# The context key allow it to appear
|
||||
# In case of a period_length of 30 days as of 2019-02-08, we want the following periods:
|
||||
# Name Stop Start
|
||||
# 1 - 30 : 2019-02-07 - 2019-01-09
|
||||
# 31 - 60 : 2019-01-08 - 2018-12-10
|
||||
# 61 - 90 : 2018-12-09 - 2018-11-10
|
||||
# 91 - 120 : 2018-11-09 - 2018-10-11
|
||||
# +120 : 2018-10-10
|
||||
ctx = self._context
|
||||
periods = {}
|
||||
date_from = fields.Date.from_string(date_from)
|
||||
start = date_from
|
||||
for i in range(5)[::-1]:
|
||||
stop = start - relativedelta(days=period_length)
|
||||
period_name = str((5-(i+1)) * period_length + 1) + '-' + str((5-i) * period_length)
|
||||
period_stop = (start - relativedelta(days=1)).strftime('%Y-%m-%d')
|
||||
if i == 0:
|
||||
period_name = '+' + str(4 * period_length)
|
||||
periods[str(i)] = {
|
||||
'name': period_name,
|
||||
'stop': period_stop,
|
||||
'start': (i!=0 and stop.strftime('%Y-%m-%d') or False),
|
||||
}
|
||||
start = stop
|
||||
|
||||
res = []
|
||||
total = []
|
||||
partner_clause = ''
|
||||
cr = self.env.cr
|
||||
user_company = self.env.company
|
||||
user_currency = user_company.currency_id
|
||||
company_ids = self._context.get('company_ids') or [user_company.id]
|
||||
move_state = ['draft', 'posted']
|
||||
if target_move == 'posted':
|
||||
move_state = ['posted']
|
||||
arg_list = (tuple(move_state), tuple(account_type))
|
||||
#build the reconciliation clause to see what partner needs to be printed
|
||||
reconciliation_clause = '(l.reconciled IS FALSE)'
|
||||
cr.execute('SELECT debit_move_id, credit_move_id FROM account_partial_reconcile where max_date > %s', (date_from,))
|
||||
reconciled_after_date = []
|
||||
for row in cr.fetchall():
|
||||
reconciled_after_date += [row[0], row[1]]
|
||||
if reconciled_after_date:
|
||||
reconciliation_clause = '(l.reconciled IS FALSE OR l.id IN %s)'
|
||||
arg_list += (tuple(reconciled_after_date),)
|
||||
if ctx.get('partner_ids'):
|
||||
partner_clause = 'AND (l.partner_id IN %s)'
|
||||
arg_list += (tuple(ctx['partner_ids'].ids),)
|
||||
if ctx.get('partner_categories'):
|
||||
partner_clause += 'AND (l.partner_id IN %s)'
|
||||
partner_ids = self.env['res.partner'].search([('category_id', 'in', ctx['partner_categories'].ids)]).ids
|
||||
arg_list += (tuple(partner_ids or [0]),)
|
||||
arg_list += (date_from, tuple(company_ids))
|
||||
|
||||
query = '''
|
||||
SELECT DISTINCT l.partner_id, res_partner.name AS name, UPPER(res_partner.name) AS UPNAME, CASE WHEN prop.value_text IS NULL THEN 'normal' ELSE prop.value_text END AS trust
|
||||
FROM account_move_line AS l
|
||||
LEFT JOIN res_partner ON l.partner_id = res_partner.id
|
||||
LEFT JOIN ir_property prop ON (prop.res_id = 'res.partner,'||res_partner.id AND prop.name='trust' AND prop.company_id=%s),
|
||||
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 + partner_clause + '''
|
||||
AND (l.date <= %s)
|
||||
AND l.company_id IN %s
|
||||
ORDER BY UPPER(res_partner.name)'''
|
||||
arg_list = (self.env.company.id,) + arg_list
|
||||
cr.execute(query, arg_list)
|
||||
|
||||
partners = cr.dictfetchall()
|
||||
# put a total of 0
|
||||
for i in range(7):
|
||||
total.append(0)
|
||||
|
||||
# Build a string like (1,2,3) for easy use in SQL query
|
||||
partner_ids = [partner['partner_id'] for partner in partners if partner['partner_id']]
|
||||
lines = dict((partner['partner_id'] or False, []) for partner in partners)
|
||||
if not partner_ids:
|
||||
return [], [], {}
|
||||
|
||||
# Use one query per period and store results in history (a list variable)
|
||||
# Each history will contain: history[1] = {'<partner_id>': <partner_debit-credit>}
|
||||
history = []
|
||||
for i in range(5):
|
||||
args_list = (tuple(move_state), tuple(account_type), tuple(partner_ids),)
|
||||
dates_query = '(COALESCE(l.date_maturity,l.date)'
|
||||
|
||||
if periods[str(i)]['start'] and periods[str(i)]['stop']:
|
||||
dates_query += ' BETWEEN %s AND %s)'
|
||||
args_list += (periods[str(i)]['start'], periods[str(i)]['stop'])
|
||||
elif periods[str(i)]['start']:
|
||||
dates_query += ' >= %s)'
|
||||
args_list += (periods[str(i)]['start'],)
|
||||
else:
|
||||
dates_query += ' <= %s)'
|
||||
args_list += (periods[str(i)]['stop'],)
|
||||
args_list += (date_from, tuple(company_ids))
|
||||
|
||||
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 IN %s) OR (l.partner_id IS NULL))
|
||||
AND ''' + dates_query + '''
|
||||
AND (l.date <= %s)
|
||||
AND l.company_id IN %s
|
||||
ORDER BY COALESCE(l.date_maturity, l.date)'''
|
||||
cr.execute(query, args_list)
|
||||
partners_amount = {}
|
||||
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).with_context(prefetch_fields=False):
|
||||
partner_id = line.partner_id.id or False
|
||||
if partner_id not in partners_amount:
|
||||
partners_amount[partner_id] = 0.0
|
||||
line_amount = line.company_id.currency_id._convert(line.balance, user_currency, user_company, date_from)
|
||||
if user_currency.is_zero(line_amount):
|
||||
continue
|
||||
for partial_line in line.matched_debit_ids:
|
||||
if partial_line.max_date <= date_from:
|
||||
line_amount += partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from)
|
||||
for partial_line in line.matched_credit_ids:
|
||||
if partial_line.max_date <= date_from:
|
||||
line_amount -= partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from)
|
||||
|
||||
if not self.env.company.currency_id.is_zero(line_amount):
|
||||
partners_amount[partner_id] += line_amount
|
||||
lines.setdefault(partner_id, [])
|
||||
lines[partner_id].append({
|
||||
'line': line,
|
||||
'amount': line_amount,
|
||||
'period': i + 1,
|
||||
})
|
||||
history.append(partners_amount)
|
||||
|
||||
# This dictionary will store the not due amount of all partners
|
||||
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) OR (l.partner_id IS NULL))
|
||||
AND (l.date <= %s)
|
||||
AND l.company_id IN %s
|
||||
ORDER BY COALESCE(l.date_maturity, l.date)'''
|
||||
cr.execute(query, (tuple(move_state), tuple(account_type), date_from, tuple(partner_ids), date_from, tuple(company_ids)))
|
||||
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):
|
||||
partner_id = line.partner_id.id or False
|
||||
if partner_id not in undue_amounts:
|
||||
undue_amounts[partner_id] = 0.0
|
||||
line_amount = line.company_id.currency_id._convert(line.balance, user_currency, user_company, date_from)
|
||||
if user_currency.is_zero(line_amount):
|
||||
continue
|
||||
for partial_line in line.matched_debit_ids:
|
||||
if partial_line.max_date <= date_from:
|
||||
line_amount += partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from)
|
||||
for partial_line in line.matched_credit_ids:
|
||||
if partial_line.max_date <= date_from:
|
||||
line_amount -= partial_line.company_id.currency_id._convert(partial_line.amount, user_currency, user_company, date_from)
|
||||
if not self.env.company.currency_id.is_zero(line_amount):
|
||||
undue_amounts[partner_id] += line_amount
|
||||
lines.setdefault(partner_id, [])
|
||||
lines[partner_id].append({
|
||||
'line': line,
|
||||
'amount': line_amount,
|
||||
'period': 6,
|
||||
})
|
||||
|
||||
for partner in partners:
|
||||
if partner['partner_id'] is None:
|
||||
partner['partner_id'] = False
|
||||
at_least_one_amount = False
|
||||
values = {}
|
||||
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']]
|
||||
|
||||
total[6] = total[6] + undue_amt
|
||||
values['direction'] = undue_amt
|
||||
if not float_is_zero(values['direction'], precision_rounding=self.env.company.currency_id.rounding):
|
||||
at_least_one_amount = True
|
||||
|
||||
for i in range(5):
|
||||
during = False
|
||||
if partner['partner_id'] in history[i]:
|
||||
during = [history[i][partner['partner_id']]]
|
||||
# Adding counter
|
||||
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.company.currency_id.rounding):
|
||||
at_least_one_amount = True
|
||||
values['total'] = sum([values['direction']] + [values[str(i)] for i in range(5)])
|
||||
# Add for total
|
||||
total[(i + 1)] += values['total']
|
||||
values['partner_id'] = partner['partner_id']
|
||||
if partner['partner_id']:
|
||||
values['name'] = len(partner['name']) >= 45 and partner['name'][0:40] + '...' or partner['name']
|
||||
values['trust'] = partner['trust']
|
||||
else:
|
||||
values['name'] = _('Unknown Partner')
|
||||
values['trust'] = False
|
||||
|
||||
if at_least_one_amount or (self._context.get('include_nullified_amount') and lines[partner['partner_id']]):
|
||||
res.append(values)
|
||||
return res, total, lines
|
||||
|
||||
@api.model
|
||||
def _get_report_values(self, docids, data=None):
|
||||
if not data.get('form') or not self.env.context.get('active_model') or not self.env.context.get('active_id'):
|
||||
raise UserError(_("Form content is missing, this report cannot be printed."))
|
||||
|
||||
total = []
|
||||
model = self.env.context.get('active_model')
|
||||
docs = self.env[model].browse(self.env.context.get('active_id'))
|
||||
|
||||
target_move = data['form'].get('target_move', 'all')
|
||||
date_from = fields.Date.from_string(data['form'].get('date_from')) or fields.Date.today()
|
||||
|
||||
if data['form']['result_selection'] == 'customer':
|
||||
account_type = ['receivable']
|
||||
elif data['form']['result_selection'] == 'supplier':
|
||||
account_type = ['payable']
|
||||
else:
|
||||
account_type = ['payable', 'receivable']
|
||||
|
||||
movelines, total, dummy = self._get_partner_move_lines(account_type, date_from, target_move, data['form']['period_length'])
|
||||
return {
|
||||
'doc_ids': self.ids,
|
||||
'doc_model': model,
|
||||
'data': data['form'],
|
||||
'docs': docs,
|
||||
'time': time,
|
||||
'get_partner_lines': movelines,
|
||||
'get_direction': total,
|
||||
'company_id': self.env['res.company'].browse(
|
||||
data['form']['company_id'][0]),
|
||||
}
|
||||
@@ -915,48 +915,6 @@ class TestReconciliationExec(TestReconciliation):
|
||||
self.assertEqual(reversed_customer_line.full_reconcile_id.id, customer_line.full_reconcile_id.id)
|
||||
|
||||
|
||||
def test_aged_report(self):
|
||||
AgedReport = self.env['report.account.report_agedpartnerbalance'].with_context(include_nullified_amount=True)
|
||||
account_type = ['receivable']
|
||||
report_date_to = time.strftime('%Y') + '-07-17'
|
||||
partner = self.env['res.partner'].create({'name': 'AgedPartner'})
|
||||
currency = self.env.company.currency_id
|
||||
|
||||
invoice = self.create_invoice_partner(currency_id=currency.id, partner_id=partner.id)
|
||||
journal = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'THE'})
|
||||
|
||||
statement = self.make_payment(invoice, journal, 50)
|
||||
|
||||
# The report searches on the create_date to dispatch reconciled lines to report periods
|
||||
# Also, in this case, there can be only 1 partial_reconcile
|
||||
statement_partial_id = statement.move_line_ids.mapped(lambda l: l.matched_credit_ids + l.matched_debit_ids)
|
||||
self.env.cr.execute('UPDATE account_partial_reconcile SET create_date = %(date)s WHERE id = %(partial_id)s',
|
||||
{'date': report_date_to + ' 00:00:00',
|
||||
'partial_id': statement_partial_id.id})
|
||||
|
||||
# Case 1: The invoice and payment are reconciled: Nothing should appear
|
||||
report_lines, total, amls = AgedReport._get_partner_move_lines(account_type, report_date_to, 'posted', 30)
|
||||
|
||||
partner_lines = [line for line in report_lines if line['partner_id'] == partner.id]
|
||||
self.assertEqual(partner_lines, [], 'The aged receivable shouldn\'t have lines at this point')
|
||||
self.assertFalse(amls.get(partner.id, False), 'The aged receivable should not have amls either')
|
||||
|
||||
# Case 2: The invoice and payment are not reconciled: we should have one line on the report
|
||||
# and 2 amls
|
||||
invoice.line_ids.with_context(invoice_id=invoice.id).remove_move_reconcile()
|
||||
report_lines, total, amls = AgedReport._get_partner_move_lines(account_type, report_date_to, 'posted', 30)
|
||||
|
||||
partner_lines = [line for line in report_lines if line['partner_id'] == partner.id]
|
||||
self.assertEqual(partner_lines, [{'trust': 'normal', '1': 0.0, '0': 0.0, 'direction': 0.0, 'partner_id': partner.id, '3': 0.0, 'total': 0.0, 'name': 'AgedPartner', '4': 0.0, '2': 0.0}],
|
||||
'We should have a line in the report for the partner')
|
||||
self.assertEqual(len(amls[partner.id]), 2, 'We should have 2 account move lines for the partner')
|
||||
|
||||
positive_line = [line for line in amls[partner.id] if line['line'].balance > 0]
|
||||
negative_line = [line for line in amls[partner.id] if line['line'].balance < 0]
|
||||
|
||||
self.assertEqual(positive_line[0]['amount'], 50.0, 'The amount of the amls should be 50')
|
||||
self.assertEqual(negative_line[0]['amount'], -50.0, 'The amount of the amls should be -50')
|
||||
|
||||
def test_revert_payment_and_reconcile_exchange(self):
|
||||
|
||||
# A reversal of a reconciled payment which created a currency exchange entry, should create reversal moves
|
||||
@@ -1025,84 +983,6 @@ class TestReconciliationExec(TestReconciliation):
|
||||
_move_revert_test_pair(payment_move, reverted_payment_move)
|
||||
_move_revert_test_pair(exchange_move, reverted_exchange_move)
|
||||
|
||||
def test_aged_report_future_payment(self):
|
||||
AgedReport = self.env['report.account.report_agedpartnerbalance'].with_context(include_nullified_amount=True)
|
||||
account_type = ['receivable']
|
||||
partner = self.env['res.partner'].create({'name': 'AgedPartner'})
|
||||
currency = self.env.company.currency_id
|
||||
|
||||
invoice = self.create_invoice_partner(currency_id=currency.id, partner_id=partner.id)
|
||||
journal = self.env['account.journal'].create({'name': 'Bank', 'type': 'bank', 'code': 'THE'})
|
||||
|
||||
statement = self.make_payment(invoice, journal, 50)
|
||||
|
||||
# Force the payment recording to take place on the invoice date
|
||||
# Although the payment due_date is in the future relative to the invoice
|
||||
# Also, in this case, there can be only 1 partial_reconcile
|
||||
statement_partial_id = statement.move_line_ids.mapped(lambda l: l.matched_credit_ids + l.matched_debit_ids)
|
||||
self.env.cr.execute('UPDATE account_partial_reconcile SET create_date = %(date)s WHERE id = %(partial_id)s',
|
||||
{'date': invoice.invoice_date,
|
||||
'partial_id': statement_partial_id.id})
|
||||
statement.flush()
|
||||
|
||||
# Case 1: report date is invoice date
|
||||
# There should be an entry for the partner
|
||||
report_date_to = invoice.invoice_date
|
||||
report_lines, total, amls = AgedReport._get_partner_move_lines(account_type, report_date_to, 'posted', 30)
|
||||
|
||||
partner_lines = [line for line in report_lines if line['partner_id'] == partner.id]
|
||||
self.assertEqual(partner_lines, [{
|
||||
'name': 'AgedPartner',
|
||||
'trust': 'normal',
|
||||
'partner_id': partner.id,
|
||||
'0': 0.0,
|
||||
'1': 0.0,
|
||||
'2': 0.0,
|
||||
'3': 0.0,
|
||||
'4': 0.0,
|
||||
'total': 50.0,
|
||||
'direction': 50.0,
|
||||
}], 'We should have a line in the report for the partner')
|
||||
self.assertEqual(len(amls[partner.id]), 1, 'We should have 1 account move lines for the partner')
|
||||
|
||||
positive_line = [line for line in amls[partner.id] if line['line'].balance > 0]
|
||||
|
||||
self.assertEqual(positive_line[0]['amount'], 50.0, 'The amount of the amls should be 50')
|
||||
|
||||
# Case 2: report date between invoice date and payment date
|
||||
# There should be an entry for the partner
|
||||
# And the amount has shifted to '1-30 due'
|
||||
report_date_to = time.strftime('%Y') + '-07-08'
|
||||
report_lines, total, amls = AgedReport._get_partner_move_lines(account_type, report_date_to, 'posted', 30)
|
||||
|
||||
partner_lines = [line for line in report_lines if line['partner_id'] == partner.id]
|
||||
self.assertEqual(partner_lines, [{
|
||||
'name': 'AgedPartner',
|
||||
'trust': 'normal',
|
||||
'partner_id': partner.id,
|
||||
'0': 0.0,
|
||||
'1': 0.0,
|
||||
'2': 0.0,
|
||||
'3': 0.0,
|
||||
'4': 50.0,
|
||||
'total': 50.0,
|
||||
'direction': 0.0,
|
||||
}], 'We should have a line in the report for the partner')
|
||||
self.assertEqual(len(amls[partner.id]), 1, 'We should have 1 account move lines for the partner')
|
||||
|
||||
positive_line = [line for line in amls[partner.id] if line['line'].balance > 0]
|
||||
|
||||
self.assertEqual(positive_line[0]['amount'], 50.0, 'The amount of the amls should be 50')
|
||||
|
||||
# Case 2: report date on payment date
|
||||
# There should not be an entry for the partner
|
||||
report_date_to = time.strftime('%Y') + '-07-15'
|
||||
report_lines, total, amls = AgedReport._get_partner_move_lines(account_type, report_date_to, 'posted', 30)
|
||||
|
||||
partner_lines = [line for line in report_lines if line['partner_id'] == partner.id]
|
||||
self.assertEqual(partner_lines, [], 'The aged receivable shouldn\'t have lines at this point')
|
||||
self.assertFalse(amls.get(partner.id, False), 'The aged receivable should not have amls either')
|
||||
|
||||
def test_partial_reconcile_currencies_02(self):
|
||||
####
|
||||
# Day 1: Invoice Cust/001 to customer (expressed in USD)
|
||||
|
||||
@@ -37,16 +37,6 @@
|
||||
print_report_name="(object._get_report_base_filename())"
|
||||
/>
|
||||
|
||||
<report
|
||||
id="action_report_aged_partner_balance"
|
||||
model="res.partner"
|
||||
string="Aged Partner Balance"
|
||||
menu="False"
|
||||
report_type="qweb-pdf"
|
||||
name="account.report_agedpartnerbalance"
|
||||
file="account.report_agedpartnerbalance"
|
||||
/>
|
||||
|
||||
<report
|
||||
id="action_report_journal"
|
||||
model="account.common.journal.report"
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<template id="report_agedpartnerbalance">
|
||||
<t t-call="web.html_container">
|
||||
<t t-call="web.internal_layout">
|
||||
<div class="page">
|
||||
<h2>Aged Partner Balance</h2>
|
||||
|
||||
<div class="row mt32">
|
||||
<div class="col-3">
|
||||
<strong>Start Date:</strong>
|
||||
<p t-esc="data['date_from']"/>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<strong>Period Length (days)</strong>
|
||||
<p t-esc="data['period_length']"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row mb32">
|
||||
<div class="col-3">
|
||||
<strong>Partner's:</strong>
|
||||
<p>
|
||||
<span t-if="data['result_selection'] == 'customer'">Receivable Accounts</span>
|
||||
<span t-if="data['result_selection'] == 'supplier'">Payable Accounts</span>
|
||||
<span t-if="data['result_selection'] == 'customer_supplier'">Receivable and Payable Accounts</span>
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-3">
|
||||
<strong>Target Moves:</strong>
|
||||
<p>
|
||||
<span t-if="data['target_move'] == 'all'">All Entries</span>
|
||||
<span t-if="data['target_move'] == 'posted'">All Posted Entries</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<table class="table table-sm">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><span>Partners</span></th>
|
||||
<th class="text-right">
|
||||
<span>Not due</span>
|
||||
</th>
|
||||
<th class="text-right"><span t-esc="data['4']['name']"/></th>
|
||||
<th class="text-right"><span t-esc="data['3']['name']"/></th>
|
||||
<th class="text-right"><span t-esc="data['2']['name']"/></th>
|
||||
<th class="text-right"><span t-esc="data['1']['name']"/></th>
|
||||
<th class="text-right"><span t-esc="data['0']['name']"/></th>
|
||||
<th class="text-right"><span>Total</span></th>
|
||||
</tr>
|
||||
<tr t-if="get_partner_lines">
|
||||
<th>Account Total</th>
|
||||
<th class="text-right"><span t-esc="get_direction[6]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
|
||||
<th class="text-right"><span t-esc="get_direction[4]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
|
||||
<th class="text-right"><span t-esc="get_direction[3]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
|
||||
<th class="text-right"><span t-esc="get_direction[2]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
|
||||
<th class="text-right"><span t-esc="get_direction[1]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
|
||||
<th class="text-right"><span t-esc="get_direction[0]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
|
||||
<th class="text-right"><span t-esc="get_direction[5]" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr t-foreach="get_partner_lines" t-as="partner">
|
||||
<td>
|
||||
<span t-esc="partner['name']"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="partner['direction']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="partner['4']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="partner['3']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="partner['2']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="partner['1']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="partner['0']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
|
||||
</td>
|
||||
<td class="text-right">
|
||||
<span t-esc="partner['total']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user