[IMP] account: put back old PDF reports for people using only the community version

This commit is contained in:
Foram Katharotiya
2015-09-10 17:52:51 +02:00
committed by qdp-odoo
parent 5ead16b9b0
commit 453adf434f
32 changed files with 1895 additions and 9 deletions
+12
View File
@@ -47,7 +47,19 @@ You could use this simplified accounting in case you work with an (external) acc
'report/account_invoice_report_view.xml',
'report/inherited_layouts.xml',
'views/account_journal_dashboard_view.xml',
'views/report_overdue.xml',
'views/web_planner_data.xml',
'views/report_overdue.xml',
'wizard/account_report_common_view.xml',
'wizard/account_report_general_ledger_view.xml',
'views/report_generalledger.xml',
'wizard/account_report_trial_balance_view.xml',
'views/report_trialbalance.xml',
'views/account_financial_report_data.xml',
'wizard/account_financial_report_view.xml',
'views/report_financial.xml',
'wizard/account_report_aged_partner_balance_view.xml',
'views/report_agedpartnerbalance.xml',
],
'demo': [
'demo/account_demo.xml',
+8
View File
@@ -35,7 +35,15 @@ class ResCompany(models.Model):
property_stock_account_output_categ_id = fields.Many2one('account.account', oldname="property_stock_account_output_categ")
property_stock_valuation_account_id = fields.Many2one('account.account')
bank_journal_ids = fields.One2many('account.journal', 'company_id', domain=[('type', '=', 'bank')], string='Bank Journals')
overdue_msg = fields.Text(string='Overdue Payments Message', translate=True,
default='''Dear Sir/Madam,
Our records indicate that some payments on your account are still due. Please find details below.
If the amount has already been paid, please disregard this notice. Otherwise, please forward us the total amount stated below.
If you have any queries regarding your account, Please contact us.
Thank you in advance for your cooperation.
Best Regards,''')
@api.multi
def compute_fiscalyear_dates(self, date):
+5
View File
@@ -3,3 +3,8 @@
import account_financial_report
import account_invoice_report
import account_overdue_report
import account_general_ledger
import account_balance
import account_report_financial
import account_aged_partner_balance
@@ -0,0 +1,299 @@
# -*- coding: utf-8 -*-
import time
from openerp import api, models
class ReportAgedPartnerBalance(models.AbstractModel):
_name = 'report.account.report_agedpartnerbalance'
def _get_partner_move_lines(self, form, account_type, date_from, target_move):
res = []
self.total_account = []
cr = self.env.cr
move_state = ['draft', 'posted']
if target_move == 'posted':
move_state = ['posted']
cr.execute('SELECT DISTINCT res_partner.id AS id,\
res_partner.name AS name \
FROM res_partner,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.reconciled IS FALSE\
AND (l.partner_id = res_partner.id)\
AND (l.date <= %s)\
ORDER BY res_partner.name', (tuple(move_state), tuple(account_type), date_from))
partners = cr.dictfetchall()
# put a total of 0
for i in range(7):
self.total_account.append(0)
# Build a string like (1,2,3) for easy use in SQL query
partner_ids = [partner['id'] for partner in partners]
if not partner_ids:
return []
# This dictionary will store the debit-credit for all partners, using partner_id as key.
totals = {}
cr.execute('SELECT l.partner_id, SUM(l.debit-l.credit) \
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)\
AND (l.date <= %s)\
GROUP BY l.partner_id ', (tuple(move_state), tuple(account_type), tuple(partner_ids), date_from,))
partner_totals = cr.fetchall()
for partner_id, amount in partner_totals:
totals[partner_id] = amount
# This dictionary will store the future or past of all partners
future_past = {}
cr.execute('SELECT l.partner_id, SUM(l.debit - l.credit) \
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.reconciled IS FALSE\
AND (l.date <= %s)\
GROUP BY l.partner_id', (tuple(move_state), tuple(account_type), date_from, tuple(partner_ids), date_from,))
partner_totals = cr.fetchall()
for partner_id, amount in partner_totals:
future_past[partner_id] = 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>}
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 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,)
cr.execute('''SELECT l.partner_id, SUM(l.debit - l.credit), 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)
AND l.reconciled IS FALSE
AND ''' + dates_query + '''
AND (l.date <= %s)
GROUP BY l.partner_id, l.id''', args_list)
partners_partial = cr.fetchall()
partners_amount = dict((partner_id, 0) for partner_id, amount, line_id in partners_partial)
for partner_id, amount, line_id in partners_partial:
partial_reconcile_ids = []
line = self.env['account.move.line'].browse(line_id)
for partial_line in (line.matched_debit_ids + line.matched_credit_ids):
if not partial_line.credit_move_id.id in partial_reconcile_ids:
partial_reconcile_ids.append(partial_line.credit_move_id.id)
if not partial_line.debit_move_id.id in partial_reconcile_ids:
partial_reconcile_ids.append(partial_line.debit_move_id.id)
if partial_reconcile_ids:
# in case of partial reconciliation, we want to keep the left amount in the oldest period
cr.execute('''SELECT MIN(COALESCE(date_maturity, date)) from account_move_line where id = %s''', (line_id,))
date = cr.fetchall()
partial = False
if 'BETWEEN' in dates_query:
partial = date and args_list[-3] <= date[0][0] <= args_list[-2]
elif '>=' in dates_query:
partial = date and date[0][0] >= form[str(i)]['start']
else:
partial = date and date[0][0] <= form[str(i)]['stop']
if partial:
# partial reconcilation
limit_date = 'COALESCE(l.date_maturity, l.date) <= %s'
cr.execute('''SELECT SUM(l.debit - l.credit)
FROM account_move_line AS l, account_move AS am
WHERE l.move_id = am.id AND am.state IN %s
AND l.id IN %s
AND ''' + limit_date, (tuple(move_state), tuple(partial_reconcile_ids), date_from))
unreconciled_amount = cr.fetchall()
partners_amount[partner_id] += unreconciled_amount[0][0]
else:
partners_amount[partner_id] += amount
history.append(partners_amount)
for partner in partners:
values = {}
# Query here is replaced by one query which gets the all the partners their 'after' value
after = False
if future_past.has_key(partner['id']): # Making sure this partner actually was found by the query
after = [ future_past[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
for i in range(5):
during = False
if history[i].has_key(partner['id']):
during = [ history[i][partner['id']] ]
# Adding counter
self.total_account[(i)] = self.total_account[(i)] + (during and during[0] or 0)
values[str(i)] = during and during[0] or 0.0
total = False
if totals.has_key( partner['id'] ):
total = [ totals[partner['id']] ]
values['total'] = total and total[0] or 0.0
## Add for total
self.total_account[(i+1)] = self.total_account[(i+1)] + (total and total[0] or 0.0)
values['name'] = partner['name']
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']
## put a total of 0
for i in range(7):
self.total_account.append(0)
totals = {}
cr.execute('SELECT SUM(l.debit - l.credit) \
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 (l.partner_id IS NULL)\
AND (account_account.internal_type IN %s)\
AND l.reconciled IS FALSE \
AND (l.date <= %s)\
',(tuple(move_state), tuple(account_type), date_from,))
total_amount = cr.fetchall()
for amount in total_amount:
totals['Unknown Partner'] = amount[0]
future_past = {}
cr.execute('SELECT SUM(l.debit-l.credit) \
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 (l.partner_id IS NULL)\
AND (account_account.internal_type IN %s)\
AND (COALESCE(l.date_maturity,l.date) > %s)\
AND l.reconciled IS FALSE\
', (tuple(move_state), tuple(account_type), date_from,))
total_amount = cr.fetchall()
for amount in total_amount:
future_past['Unknown Partner'] = amount[0]
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,)
cr.execute('SELECT SUM(l.debit - l.credit)\
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 l.reconciled IS FALSE\
AND ' + dates_query + '\
AND (l.date <= %s)\
GROUP BY l.partner_id', args_list)
total_amount = cr.fetchall()
history_data = {}
for amount in total_amount:
history_data['Unknown Partner'] = amount[0]
history.append(history_data)
values = {}
after = False
if future_past.has_key('Unknown Partner'):
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 history[i].has_key('Unknown Partner'):
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
total = False
if totals.has_key( 'Unknown Partner' ):
total = [ totals['Unknown Partner'] ]
values['total'] = total and total[0] or 0.0
## Add for total
self.total_account[(i+1)] = self.total_account[(i+1)] + (total and total[0] or 0.0)
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
@api.multi
def render_html(self, data):
self.total_account = []
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 = data['form'].get('date_from', time.strftime('%Y-%m-%d'))
if data['form']['result_selection'] == 'customer':
account_type = ['receivable']
elif data['form']['result_selection'] == 'supplier':
account_type = ['payable']
else:
account_type = ['payable','receivable']
without_partner_movelines = self._get_move_lines_with_out_partner(data['form'], account_type, date_from, target_move)
partner_movelines = self._get_partner_move_lines(data['form'], account_type, date_from, target_move)
movelines = partner_movelines + without_partner_movelines
docargs = {
'doc_ids': self.ids,
'doc_model': model,
'data': data['form'],
'docs': docs,
'time': time,
'get_partner_lines': movelines,
'get_direction': self.total_account,
}
return self.env['report'].render('account.report_agedpartnerbalance', docargs)
+74
View File
@@ -0,0 +1,74 @@
# -*- coding: utf-8 -*-
import time
from openerp import api, models
class ReportTrialBalance(models.AbstractModel):
_name = 'report.account.report_trialbalance'
def _get_accounts(self, accounts, display_account):
""" compute the balance, debit and credit for the provided accounts
:Arguments:
`accounts`: list of accounts record,
`display_account`: it's used to display either all accounts or those accounts which balance is > 0
:Returns a list of dictionary of Accounts with following key and value
`name`: Account name,
`code`: Account code,
`credit`: total amount of credit,
`debit`: total amount of debit,
`balance`: total amount of balance,
"""
account_result = {}
# Prepare sql query base on selected parameters from wizard
tables, where_clause, where_params = self.env['account.move.line']._query_get()
tables = tables.replace('"','')
if not tables:
tables = 'account_move_line'
wheres = [""]
if where_clause.strip():
wheres.append(where_clause.strip())
filters = " AND ".join(wheres)
# compute the balance, debit and credit for the provided accounts
request = ("SELECT account_id AS id, SUM(debit) AS debit, SUM(credit) AS credit, (SUM(debit) - SUM(credit)) AS balance" +\
" FROM " + tables + " WHERE account_id IN %s " + filters + " GROUP BY account_id")
params = (tuple(accounts.ids),) + tuple(where_params)
self.env.cr.execute(request, params)
for row in self.env.cr.dictfetchall():
account_result[row.pop('id')] = row
account_res = []
for account in accounts:
res = dict((fn, 0.0) for fn in ['credit', 'debit', 'balance'])
currency = account.currency_id and account.currency_id or account.company_id.currency_id
res['code'] = account.code
res['name'] = account.name
if account.id in account_result.keys():
res['debit'] = account_result[account.id].get('debit')
res['credit'] = account_result[account.id].get('credit')
res['balance'] = account_result[account.id].get('balance')
if display_account == 'all':
account_res.append(res)
if display_account in ['movement', 'not_zero'] and not currency.is_zero(res['balance']):
account_res.append(res)
return account_res
@api.multi
def render_html(self, data):
self.model = self.env.context.get('active_model')
docs = self.env[self.model].browse(self.env.context.get('active_id'))
display_account = data['form'].get('display_account')
accounts = self.env['account.account'].search([])
account_res = self.with_context(data['form'].get('used_context'))._get_accounts(accounts, display_account)
docargs = {
'doc_ids': self.ids,
'doc_model': self.model,
'data': data['form'],
'docs': docs,
'time': time,
'Accounts': account_res,
}
return self.env['report'].render('account.report_trialbalance', docargs)
@@ -0,0 +1,133 @@
# -*- coding: utf-8 -*-
import time
from openerp import api, models
class ReportGeneralLedger(models.AbstractModel):
_name = 'report.account.report_generalledger'
def _get_account_move_entry(self, accounts, init_balance, sortby, display_account):
"""
:param:
accounts: the recordset of accounts
init_balance: boolean value of initial_balance
sortby: sorting by date or partner and journal
display_account: type of account(receivable, payable and both)
Returns a dictionary of accounts with following key and value {
'code': account code,
'name': account name,
'debit': sum of total debit amount,
'credit': sum of total credit amount,
'balance': total balance,
'amount_currency': sum of amount_currency,
'move_lines': list of move line
}
"""
cr = self.env.cr
MoveLine = self.env['account.move.line']
move_lines = dict(map(lambda x: (x, []), accounts.ids))
# Prepare initial sql query and Get the initial move lines
if init_balance:
init_tables, init_where_clause, init_where_params = MoveLine.with_context(date_to=self.env.context.get('date_from'), date_from=False)._query_get()
init_wheres = [""]
if init_where_clause.strip():
init_wheres.append(init_where_clause.strip())
init_filters = " AND ".join(init_wheres)
filters = init_filters.replace('account_move_line__move_id', 'm').replace('account_move_line', 'l')
sql = ("SELECT 0 AS lid, l.account_id AS account_id, '' AS ldate, '' AS lcode, NULL AS amount_currency, '' AS lref, 'Initial Balance' AS lname, COALESCE(SUM(l.debit),0.0) AS debit, COALESCE(SUM(l.credit),0.0) AS credit, COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) as balance, '' AS lpartner_id,\
'' AS move_name, '' AS mmove_id, '' AS currency_code,\
NULL AS currency_id,\
'' AS invoice_id, '' AS invoice_type, '' AS invoice_number,\
'' AS partner_name\
FROM account_move_line l\
LEFT JOIN account_move m ON (l.move_id=m.id)\
LEFT JOIN res_currency c ON (l.currency_id=c.id)\
LEFT JOIN res_partner p ON (l.partner_id=p.id)\
LEFT JOIN account_invoice i ON (m.id =i.move_id)\
JOIN account_journal j ON (l.journal_id=j.id)\
WHERE l.account_id IN %s" + filters + ' GROUP BY l.account_id')
params = (tuple(accounts.ids),) + tuple(init_where_params)
cr.execute(sql, params)
for row in cr.dictfetchall():
move_lines[row.pop('account_id')].append(row)
sql_sort = 'l.date, l.move_id'
if sortby == 'sort_journal_partner':
sql_sort = 'j.code, p.name, l.move_id'
# Prepare sql query base on selected parameters from wizard
tables, where_clause, where_params = MoveLine._query_get()
wheres = [""]
if where_clause.strip():
wheres.append(where_clause.strip())
filters = " AND ".join(wheres)
filters = filters.replace('account_move_line__move_id', 'm').replace('account_move_line', 'l')
# Get move lines base on sql query and Calculate the total balance of move lines
sql = ('SELECT l.id AS lid, l.account_id AS account_id, l.date AS ldate, j.code AS lcode, l.currency_id, l.amount_currency, l.ref AS lref, l.name AS lname, COALESCE(l.debit,0) AS debit, COALESCE(l.credit,0) AS credit, COALESCE(SUM(l.debit),0) - COALESCE(SUM(l.credit), 0) AS balance,\
m.name AS move_name, c.symbol AS currency_code, p.name AS partner_name\
FROM account_move_line l\
JOIN account_move m ON (l.move_id=m.id)\
LEFT JOIN res_currency c ON (l.currency_id=c.id)\
LEFT JOIN res_partner p ON (l.partner_id=p.id)\
JOIN account_journal j ON (l.journal_id=j.id)\
JOIN account_account acc ON (l.account_id = acc.id) \
WHERE l.account_id IN %s ' + filters + ' GROUP BY l.id, l.account_id, l.date, j.code, l.currency_id, l.amount_currency, l.ref, l.name, m.name, c.symbol, p.name ORDER BY ' + sql_sort)
params = (tuple(accounts.ids),) + tuple(where_params)
cr.execute(sql, params)
for row in cr.dictfetchall():
balance = 0
for line in move_lines.get(row['account_id']):
balance += line['debit'] - line['credit']
row['balance'] += balance
move_lines[row.pop('account_id')].append(row)
# Calculate the debit, credit and balance for Accounts
account_res = []
for account in accounts:
currency = account.currency_id and account.currency_id or account.company_id.currency_id
res = dict((fn, 0.0) for fn in ['credit', 'debit', 'balance'])
res['code'] = account.code
res['name'] = account.name
res['move_lines'] = move_lines[account.id]
for line in res.get('move_lines'):
res['debit'] += line['debit']
res['credit'] += line['credit']
res['balance'] = line['balance']
if display_account == 'all':
account_res.append(res)
if display_account == 'movement' and res.get('move_lines'):
account_res.append(res)
if display_account == 'not_zero' and not currency.is_zero(res['balance']):
account_res.append(res)
return account_res
@api.multi
def render_html(self, data):
self.model = self.env.context.get('active_model')
docs = self.env[self.model].browse(self.env.context.get('active_id'))
init_balance = data['form'].get('initial_balance', True)
sortby = data['form'].get('sortby', 'sort_date')
display_account = data['form']['display_account']
codes = []
if data['form'].get('journal_ids', False):
codes = [journal.code for journal in self.env['account.journal'].search([('id', 'in', data['form']['journal_ids'])])]
accounts = self.env['account.account'].search([])
accounts_res = self.with_context(data['form'].get('used_context',{}))._get_account_move_entry(accounts, init_balance, sortby, display_account)
docargs = {
'doc_ids': self.ids,
'doc_model': self.model,
'data': data['form'],
'docs': docs,
'time': time,
'Accounts': accounts_res,
'print_journal': codes,
}
return self.env['report'].render('account.report_generalledger', docargs)
@@ -0,0 +1,69 @@
# -*- coding: utf-8 -*-
import time
from openerp import api, fields, models
class ReportOverdue(models.AbstractModel):
_name = 'report.account.report_overdue'
def _get_account_move_lines(self, partner_ids):
res = dict(map(lambda x:(x,[]), partner_ids))
self.env.cr.execute("SELECT m.name AS move_id, l.date, l.name, l.ref, l.date_maturity, l.partner_id, l.blocked, l.amount_currency, l.currency_id, "
"CASE WHEN at.type = 'receivable' "
"THEN SUM(l.debit) "
"ELSE SUM(l.credit * -1) "
"END AS debit, "
"CASE WHEN at.type = 'receivable' "
"THEN SUM(l.credit) "
"ELSE SUM(l.debit * -1) "
"END AS credit, "
"CASE WHEN l.date_maturity < %s "
"THEN SUM(l.debit - l.credit) "
"ELSE 0 "
"END AS mat "
"FROM account_move_line l "
"JOIN account_account_type at ON (l.user_type_id = at.id) "
"JOIN account_move m ON (l.move_id = m.id) "
"WHERE l.partner_id IN %s AND at.type IN ('receivable', 'payable') GROUP BY l.date, l.name, l.ref, l.date_maturity, l.partner_id, at.type, l.blocked, l.amount_currency, l.currency_id, l.move_id, m.name", (((fields.date.today(), ) + (tuple(partner_ids),))))
for row in self.env.cr.dictfetchall():
res[row.pop('partner_id')].append(row)
return res
@api.multi
def render_html(self, data):
totals = {}
lines = self._get_account_move_lines(self.ids)
lines_to_display = {}
company_currency = self.env.user.company_id.currency_id
for partner_id in self.ids:
lines_to_display[partner_id] = {}
totals[partner_id] = {}
for line_tmp in lines[partner_id]:
line = line_tmp.copy()
currency = line['currency_id'] and self.env['res.currency'].browse(line['currency_id']) or company_currency
if currency not in lines_to_display[partner_id]:
lines_to_display[partner_id][currency] = []
totals[partner_id][currency] = dict((fn, 0.0) for fn in ['due', 'paid', 'mat', 'total'])
if line['debit'] and line['currency_id']:
line['debit'] = line['amount_currency']
if line['credit'] and line['currency_id']:
line['credit'] = line['amount_currency']
if line['mat'] and line['currency_id']:
line['mat'] = line['amount_currency']
lines_to_display[partner_id][currency].append(line)
if not line['blocked']:
totals[partner_id][currency]['due'] += line['debit']
totals[partner_id][currency]['paid'] += line['credit']
totals[partner_id][currency]['mat'] += line['mat']
totals[partner_id][currency]['total'] += line['debit'] - line['credit']
docargs = {
'doc_ids': self.ids,
'doc_model': 'res.partner',
'docs': self.env['res.partner'].browse(self.ids),
'time': time,
'Lines': lines_to_display,
'Totals': totals,
'Date': fields.date.today(),
}
return self.env['report'].render('account.report_overdue', values=docargs)
@@ -0,0 +1,156 @@
# -*- coding: utf-8 -*-
import time
from openerp import api, models
class ReportFinancial(models.AbstractModel):
_name = 'report.account.report_financial'
def _compute_account_balance(self, accounts):
""" compute the balance, debit and credit for the provided accounts
"""
mapping = {
'balance': "COALESCE(SUM(debit),0) - COALESCE(SUM(credit), 0) as balance",
'debit': "COALESCE(SUM(debit), 0) as debit",
'credit': "COALESCE(SUM(credit), 0) as credit",
}
res = {}
for account in accounts:
res[account.id] = dict((fn, 0.0) for fn in mapping.keys())
if accounts:
tables, where_clause, where_params = self.env['account.move.line']._query_get()
tables = tables.replace('"', '') if tables else "account_move_line"
wheres = [""]
if where_clause.strip():
wheres.append(where_clause.strip())
filters = " AND ".join(wheres)
request = "SELECT account_id as id, " + ', '.join(mapping.values()) + \
" FROM " + tables + \
" WHERE account_id IN %s " \
+ filters + \
" GROUP BY account_id"
params = (tuple(accounts._ids),) + tuple(where_params)
self.env.cr.execute(request, params)
for row in self.env.cr.dictfetchall():
res[row['id']] = row
return res
def _compute_report_balance(self, reports):
'''returns a dictionary with key=the ID of a record and value=the credit, debit and balance amount
computed for this record. If the record is of type :
'accounts' : it's the sum of the linked accounts
'account_type' : it's the sum of leaf accoutns with such an account_type
'account_report' : it's the amount of the related report
'sum' : it's the sum of the children of this record (aka a 'view' record)'''
res = {}
fields = ['credit', 'debit', 'balance']
for report in reports:
if report.id in res:
continue
res[report.id] = dict((fn, 0.0) for fn in fields)
if report.type == 'accounts':
# it's the sum of the linked accounts
res[report.id]['account'] = self._compute_account_balance(report.account_ids)
for value in res[report.id]['account'].values():
for field in fields:
res[report.id][field] += value.get(field)
elif report.type == 'account_type':
# it's the sum the leaf accounts with such an account type
accounts = self.env['account.account'].search([('user_type_id', 'in', report.account_type_ids.ids)])
res[report.id]['account'] = self._compute_account_balance(accounts)
for value in res[report.id]['account'].values():
for field in fields:
res[report.id][field] += value.get(field)
elif report.type == 'account_report' and report.account_report_id:
# it's the amount of the linked report
res2 = self._compute_report_balance(report.account_report_id)
for key, value in res2.items():
for field in fields:
res[report.id][field] += value[field]
elif report.type == 'sum':
# it's the sum of the children of this account.report
res2 = self._compute_report_balance(report.children_ids)
for key, value in res2.items():
for field in fields:
res[report.id][field] += value[field]
return res
def get_account_lines(self, data):
lines = []
account_report = self.env['account.financial.report'].search([('id', '=', data['account_report_id'][0])])
child_reports = account_report._get_children_by_order()
res = self.with_context(data.get('used_context'))._compute_report_balance(child_reports)
if data['enable_filter']:
comparison_res = self.with_context(data.get('comparison_context'))._compute_report_balance(child_reports)
for report_id, value in comparison_res.items():
res[report_id]['comp_bal'] = value['balance']
report_acc = res[report_id].get('account')
if report_acc:
for account_id, val in comparison_res[report_id].get('account').items():
report_acc[account_id]['comp_bal'] = val['balance']
for report in child_reports:
vals = {
'name': report.name,
'balance': res[report.id]['balance'] * report.sign,
'type': 'report',
'level': bool(report.style_overwrite) and report.style_overwrite or report.level,
'account_type': report.type or False, #used to underline the financial report balances
}
if data['debit_credit']:
vals['debit'] = res[report.id]['debit']
vals['credit'] = res[report.id]['credit']
if data['enable_filter']:
vals['balance_cmp'] = res[report.id]['comp_bal'] * report.sign
lines.append(vals)
if report.display_detail == 'no_detail':
#the rest of the loop is used to display the details of the financial report, so it's not needed here.
continue
if res[report.id].get('account'):
for account_id, value in res[report.id]['account'].items():
#if there are accounts to display, we add them to the lines with a level equals to their level in
#the COA + 1 (to avoid having them with a too low level that would conflicts with the level of data
#financial reports for Assets, liabilities...)
flag = False
account = self.env['account.account'].browse(account_id)
vals = {
'name': account.code + ' ' + account.name,
'balance': value['balance'] * report.sign or 0.0,
'type': 'account',
'level': report.display_detail == 'detail_with_hierarchy' and 4,
'account_type': account.internal_type,
}
if data['debit_credit']:
vals['debit'] = value['debit']
vals['credit'] = value['credit']
if not account.company_id.currency_id.is_zero(vals['debit']) or not account.company_id.currency_id.is_zero(vals['credit']):
flag = True
if not account.company_id.currency_id.is_zero(vals['balance']):
flag = True
if data['enable_filter']:
vals['balance_cmp'] = value['comp_bal'] * report.sign
if not account.company_id.currency_id.is_zero(vals['balance_cmp']):
flag = True
if flag:
lines.append(vals)
return lines
@api.multi
def render_html(self, data):
self.model = self.env.context.get('active_model')
docs = self.env[self.model].browse(self.env.context.get('active_id'))
report_lines = self.get_account_lines(data.get('form'))
docargs = {
'doc_ids': self.ids,
'doc_model': self.model,
'data': data['form'],
'docs': docs,
'time': time,
'get_account_lines': report_lines,
}
return self.env['report'].render('account.report_financial', docargs)
+1 -9
View File
@@ -72,18 +72,10 @@
from openerp.tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_general_journal',wiz_data=data_dict, context=ctx, our_module='account')
-
Print the General Ledger Report in Normal Mode
Print the General Ledger Report (in Landscape Mode)
-
!python {model: account.account}: |
ctx={}
data_dict = {'chart_account_id':ref('account.chart0'),'landscape':False}
from openerp.tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_general_ledger_menu',wiz_data=data_dict, context=ctx, our_module='account')
-
Print the General Ledger Report in Landscape Mode
-
!python {model: account.account}: |
ctx={'landscape': True}
data_dict = {'chart_account_id':ref('account.chart0')}
from openerp.tools import test_reports
test_reports.try_report_action(cr, uid, 'action_account_general_ledger_menu',wiz_data=data_dict, context=ctx, our_module='account')
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<!--
Financial Reports
-->
<record id="account_financial_report_profitandloss0" model="account.financial.report">
<field name="name">Profit and Loss</field>
<field name="sign" eval="-1" />
<field name="type">sum</field>
</record>
<record id="account_financial_report_income0" model="account.financial.report">
<field name="name">Income</field>
<field name="sign" eval="-1" />
<field name="parent_id" ref="account_financial_report_profitandloss0"/>
<field name="display_detail">detail_with_hierarchy</field>
<field name="type">account_type</field>
<field name="account_type_ids" eval="[(4,ref('account.data_account_type_other_income')), (4,ref('account.data_account_type_revenue'))]"/>
</record>
<record id="account_financial_report_expense0" model="account.financial.report">
<field name="name">Expense</field>
<field name="sign" eval="-1" />
<field name="parent_id" ref="account_financial_report_profitandloss0"/>
<field name="display_detail">detail_with_hierarchy</field>
<field name="type">account_type</field>
<field name="account_type_ids" eval="[(4,ref('account.data_account_type_expenses')), (4,ref('account.data_account_type_direct_costs')), (4,ref('account.data_account_type_depreciation'))]"/>
</record>
<record id="account_financial_report_balancesheet0" model="account.financial.report">
<field name="name">Balance Sheet</field>
<field name="type">sum</field>
</record>
<record id="account_financial_report_assets0" model="account.financial.report">
<field name="name">Assets</field>
<field name="parent_id" ref="account_financial_report_balancesheet0"/>
<field name="display_detail">detail_with_hierarchy</field>
<field name="type">account_type</field>
<field name="account_type_ids" eval="[(4,ref('account.data_account_type_receivable')), (4,ref('account.data_account_type_liquidity')), (4,ref('account.data_account_type_current_assets')), (4,ref('account.data_account_type_non_current_assets'), (4,ref('account.data_account_type_prepayments'))), (4,ref('account.data_account_type_fixed_assets'))]"/>
</record>
<record id="account_financial_report_liabilitysum0" model="account.financial.report">
<field name="name">Liability</field>
<field name="parent_id" ref="account_financial_report_balancesheet0"/>
<field name="display_detail">no_detail</field>
<field name="type">sum</field>
</record>
<record id="account_financial_report_liability0" model="account.financial.report">
<field name="name">Liability</field>
<field name="parent_id" ref="account_financial_report_liabilitysum0"/>
<field name="display_detail">detail_with_hierarchy</field>
<field name="type">account_type</field>
<field name="account_type_ids" eval="[(4,ref('account.data_account_type_payable')), (4,ref('account.data_account_type_equity')), (4,ref('account.data_account_type_current_liabilities')), (4,ref('account.data_account_type_non_current_liabilities'))]"/>
</record>
<record id="account_financial_report_profitloss_toreport0" model="account.financial.report">
<field name="name">Profit (Loss) to report</field>
<field name="parent_id" ref="account_financial_report_liabilitysum0"/>
<field name="display_detail">no_detail</field>
<field name="type">account_report</field>
<field name="account_report_id" ref="account_financial_report_profitandloss0"/>
</record>
</data>
</odoo>
@@ -27,6 +27,9 @@
<menuitem id="base.menu_action_currency_form" name="Currencies" parent="menu_config_multi_currency" sequence="20" groups="base.group_no_one"/>
<menuitem id="menu_finance_legal_statement" name="PDF Reports" parent="account.menu_finance_reports"/>
<menuitem id="menu_account_reports" name="Financial Reports" parent="menu_finance_configuration"/>
</data>
</openerp>
+46
View File
@@ -23,5 +23,51 @@
attachment_use="False"
/>
<report
id="action_report_print_overdue"
model="res.partner"
report_type="qweb-pdf"
string="Due Payments"
name="account.report_overdue"
file="account.report_overdue"
/>
<report
id="action_report_general_ledger"
model="account.report.general.ledger"
string="General Ledger"
report_type="qweb-pdf"
name="account.report_generalledger"
file="account.report_generalledger"
/>
<report
id="action_report_trial_balance"
model="account.balance.report"
string="Trial Balance"
report_type="qweb-pdf"
name="account.report_trialbalance"
file="account.report_trialbalance"
/>
<report
id="action_report_financial"
model="account.financial.report"
string="Financial report"
report_type="qweb-pdf"
name="account.report_financial"
file="account.report_financial"
/>
<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"
/>
</data>
</openerp>
+93
View File
@@ -1798,6 +1798,99 @@
parent="menu_finance_payables"
action="base.action_partner_supplier_form" sequence="100"/>
<!-- Account Financial Report -->
<record id="view_account_financial_report_form" model="ir.ui.view">
<field name="name">account.financial.report.form</field>
<field name="model">account.financial.report</field>
<field name="arch" type="xml">
<form string="Account Report">
<group col="4">
<field name="name"/>
<field name="parent_id"/>
<field name="sequence"/>
<field name="type"/>
<field name="sign"/>
<field name="style_overwrite"/>
</group>
<notebook attrs="{'invisible': [('type','not in',['accounts','account_type', 'account_report'])]}">
<page string="Report">
<group>
<field name="display_detail" attrs="{'invisible': [('type','not in',['accounts','account_type'])]}"/>
<field name="account_report_id" attrs="{'invisible': [('type', '!=', 'account_report')]}"/>
</group>
<field name="account_ids" attrs="{'invisible': [('type', '!=', 'accounts')]}"/>
<field name="account_type_ids" attrs="{'invisible': [('type', '!=', 'account_type')]}"/>
</page>
</notebook>
</form>
</field>
</record>
<record id="view_account_financial_report_tree" model="ir.ui.view">
<field name="name">account.financial.report.tree</field>
<field name="model">account.financial.report</field>
<field name="arch" type="xml">
<tree string="Account Report">
<field name="name"/>
<field name="parent_id" invisible="1"/>
<field name="type"/>
<field name="account_report_id"/>
</tree>
</field>
</record>
<record id="view_account_financial_report_search" model="ir.ui.view">
<field name="name">account.financial.report.search</field>
<field name="model">account.financial.report</field>
<field name="arch" type="xml">
<search string="Account Report">
<field name="name" string="Account Report"/>
<field name="type"/>
<field name="account_report_id"/>
<group expand="0" string="Group By">
<filter string="Parent Report" icon="terp-folder-orange" domain="" context="{'group_by':'parent_id'}"/>
<filter string="Report Type" icon="terp-stock_symbol-selection" domain="[]" context="{'group_by':'type'}"/>
</group>
</search>
</field>
</record>
<record id="action_account_financial_report_tree" model="ir.actions.act_window">
<field name="name">Financial Reports</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.financial.report</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="search_view_id" ref="view_account_financial_report_search"/>
<field name="view_id" ref="view_account_financial_report_tree"/>
</record>
<menuitem id="menu_account_financial_reports_tree" name="Account Reports" parent="menu_account_reports" action="action_account_financial_report_tree"/>
<record id="view_account_report_tree_hierarchy" model="ir.ui.view">
<field name="name">account.report.hierarchy</field>
<field name="model">account.financial.report</field>
<field name="field_parent">children_ids</field>
<field name="arch" type="xml">
<tree string="Account Reports Hierarchy">
<field name="name"/>
<field name="type"/>
<field name="parent_id" invisible="1"/>
<field name="account_report_id"/>
</tree>
</field>
</record>
<record id="action_account_report_tree_hierarchy" model="ir.actions.act_window">
<field name="name">Financial Reports Hierarchy</field>
<field name="res_model">account.financial.report</field>
<field name="view_type">tree</field>
<field name="view_id" ref="view_account_report_tree_hierarchy"/>
<field name="domain">[('parent_id','=',False)]</field>
</record>
<menuitem id="menu_account_report_tree_hierarchy" name="Account Reports Hierarchy" parent="menu_account_reports" action="action_account_report_tree_hierarchy"/>
</data>
</openerp>
+6
View File
@@ -14,6 +14,12 @@
<field name="cash_account_code_prefix" groups="base.group_no_one"/>
<field name="accounts_code_digits" groups="base.group_no_one"/>
</xpath>
<notebook position="inside">
<page string="Overdue Payments">
<separator string="Overdue Payments Message" colspan="4"/>
<field name="overdue_msg" nolabel="1" colspan ="4"/>
</page>
</notebook>
</field>
</record>
@@ -0,0 +1,95 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_agedpartnerbalance">
<t t-call="report.html_container">
<t t-call="report.internal_layout">
<div class="page">
<h2>Aged Trial Balance</h2>
<div class="row mt32">
<div class="col-xs-3">
<strong>Start Date:</strong>
<p t-esc="data['date_from']"/>
</div>
<div class="col-xs-3">
<strong>Period Length (days)</strong>
<p t-esc="data['period_length']"/>
</div>
</div>
<div class="row mb32">
<div class="col-xs-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-xs-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-condensed">
<thead>
<tr>
<th>Partners</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">Total</th>
</tr>
<tr t-if="get_partner_lines">
<th>Account Total</th>
<th class="text-right"><span t-esc="get_direction[6]" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/></th>
<th class="text-right"><span t-esc="get_direction[4]" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/></th>
<th class="text-right"><span t-esc="get_direction[3]" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/></th>
<th class="text-right"><span t-esc="get_direction[2]" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/></th>
<th class="text-right"><span t-esc="get_direction[1]" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/></th>
<th class="text-right"><span t-esc="get_direction[0]" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/></th>
<th class="text-right"><span t-esc="get_direction[5]" t-esc-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-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="partner['4']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="partner['3']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="partner['2']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="partner['1']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="partner['0']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="partner['total']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
</tr>
</tbody>
</table>
</div>
</t>
</t>
</template>
</odoo>
+110
View File
@@ -0,0 +1,110 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_financial">
<t t-call="report.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="report.internal_layout">
<div class="page">
<h2 t-esc="data['account_report_id'][1]"/>
<div class="row mt32 mb32">
<div class="col-xs-4">
<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 class="col-xs-4">
<p>
<t t-if="data['date_from']"><strong>Date from :</strong> <span t-esc="data['date_from']"/><br/></t>
<t t-if="data['date_to']"><strong>Date to :</strong> <span t-esc="data['date_to']"/></t>
</p>
</div>
</div>
<table class="table table-condensed" t-if="data['debit_credit'] == 1">
<thead>
<tr>
<th>Name</th>
<th class="text-right">Debit</th>
<th class="text-right">Credit</th>
<th class="text-right">Balance</th>
</tr>
</thead>
<tbody>
<tr t-foreach="get_account_lines" t-as="a">
<t t-if="a['level'] != 0">
<t t-if="a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: normal;'"/></t>
<t t-if="not a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: bold;'"/></t>
<td>
<span style="color: white;" t-esc="'..' * a.get('level', 0)"/>
<span t-att-style="style" t-esc="a.get('name')"/>
</td>
<td class="text-right" style="white-space: text-nowrap;">
<span t-att-style="style" t-esc="a.get('debit')" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right" style="white-space: text-nowrap;">
<span t-att-style="style" t-esc="a.get('credit')" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right" style="white-space: text-nowrap;">
<span t-att-style="style" t-esc="a.get('balance')" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
</t>
</tr>
</tbody>
</table>
<table class="table table-condensed" t-if="not data['enable_filter'] and not data['debit_credit']">
<thead>
<tr>
<th>Name</th>
<th class="text-right">Balance</th>
</tr>
</thead>
<tbody>
<tr t-foreach="get_account_lines" t-as="a">
<t t-if="a['level'] != 0">
<t t-if="a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: normal;'"/></t>
<t t-if="not a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: bold;'"/></t>
<td>
<span style="color: white;" t-esc="'..' * a.get('level', 0)"/>
<span t-att-style="style" t-esc="a.get('name')"/>
</td>
<td class="text-right"><span t-att-style="style" t-esc="a.get('balance')" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/></td>
</t>
</tr>
</tbody>
</table>
<table class="table table-condensed" t-if="data['enable_filter'] == 1 and not data['debit_credit']">
<thead>
<tr>
<th>Name</th>
<th class="text-right">Balance</th>
<th class="text-right"><span t-esc="data['label_filter']"/></th>
</tr>
</thead>
<tbody>
<tr t-foreach="get_account_lines" t-as="a">
<t t-if="a['level'] != 0">
<t t-if="a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: normal;'"/></t>
<t t-if="not a.get('level') &gt; 3"><t t-set="style" t-value="'font-weight: bold;'"/></t>
<td>
<span style="color: white;" t-esc="'..'"/>
<span t-att-style="style" t-esc="a.get('name')"/>
</td>
<td class="text-right"><span t-att-style="style" t-esc="a.get('balance')" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/></td>
<td class="text-right"><span t-att-style="style" t-esc="a.get('balance_cmp')"/></td>
</t>
</tr>
</tbody>
</table>
</div>
</t>
</t>
</t>
</template>
</odoo>
@@ -0,0 +1,107 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_generalledger">
<t t-call="report.html_container">
<t t-set="data_report_margin_top" t-value="12"/>
<t t-set="data_report_header_spacing" t-value="9"/>
<t t-set="data_report_dpi" t-value="110"/>
<t t-call="report.internal_layout">
<div class="page">
<h2><span t-esc="res_company.name"/>: General ledger</h2>
<div class="row mt32">
<div class="col-xs-4">
<strong>Journals:</strong>
<p t-esc="', '.join([ lt or '' for lt in print_journal ])"/>
</div>
<div class="col-xs-4">
<strong>Display Account</strong>
<p>
<span t-if="data['display_account'] == 'all'">All accounts'</span>
<span t-if="data['display_account'] == 'movement'">With movements</span>
<span t-if="data['display_account'] == 'not_zero'">With balance not equal to zero</span>
</p>
</div>
<div class="col-xs-4">
<strong>Target Moves:</strong>
<p t-if="data['target_move'] == 'all'">All Entries</p>
<p t-if="data['target_move'] == 'posted'">All Posted Entries</p>
</div>
</div>
<div class="row mb32">
<div class="col-xs-4">
<strong>Sorted By:</strong>
<p t-if="data['sortby'] == 'sort_date'">Date</p>
<p t-if="data['sortby'] == 'sort_journal_partner'">Journal and Partner</p>
</div>
<div class="col-xs-4">
<t t-if="data['date_from']"><strong>Date from :</strong> <span t-esc="data['date_from']"/><br/></t>
<t t-if="data['date_to']"><strong>Date to :</strong> <span t-esc="data['date_to']"/></t>
</div>
</div>
<table class="table table-condensed">
<thead>
<tr class="text-center">
<th>Date</th>
<th>JRNL</th>
<th>Partner</th>
<th>Ref</th>
<th>Move</th>
<th>Entry Label</th>
<th>Debit</th>
<th>Credit</th>
<th>Balance</th>
<th groups="base.group_multi_currency">Currency</th>
</tr>
</thead>
<tbody>
<t t-foreach="Accounts" t-as="account">
<tr style="font-weight: bold;">
<td colspan="6">
<span style="color: white;" t-esc="'..'"/>
<span t-esc="account['code']"/>
<span t-esc="account['name']"/>
</td>
<td class="text-right">
<span t-esc="account['debit']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="account['credit']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="account['balance']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td groups="base.group_multi_currency"/>
</tr>
<tr t-foreach="account['move_lines']" t-as="line">
<td><span t-esc="line['ldate']"/></td>
<td><span t-esc="line['lcode']"/></td>
<td><span t-esc="line['partner_name']"/></td>
<td><span t-if="line['lref']" t-esc="line['lref']"/></td>
<td><span t-esc="line['move_name']"/></td>
<td><span t-esc="line['lname']"/></td>
<td class="text-right">
<span t-esc="line['debit']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="line['credit']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-esc="line['balance']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right" groups="base.group_multi_currency">
<span t-esc="line['amount_currency'] if line['amount_currency'] > 0.00 else ''"/>
<span t-esc="line['currency_code'] if line['amount_currency'] > 0.00 else ''"/>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</t>
</t>
</template>
</odoo>
+88
View File
@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="account.report_overdue_document">
<t t-call="report.external_layout">
<div class="page">
<div class="row">
<div class="col-xs-5 col-xs-offset-7">
<span t-field="o.name"/><br/>
<span t-raw="o._address_display(None, None)[o.id].replace('\n\n', '\n').replace('\n', '&lt;br&gt;')"/>
<span t-field="o.vat"/>
</div>
<p>
Document: Customer account statement<br/>
Date: <span t-esc="Date"/><br/>
<t t-if="o.ref">Customer ref: <span t-field="o.ref"/></t>
</p>
<t t-if="Lines[o.id]">
<span t-field="res_company.overdue_msg"/>
<table class="table table-condensed" t-foreach="Lines[o.id]" t-as="currency">
<thead>
<tr>
<th>Reference number</th>
<th class="text-center">Date</th>
<th class="text-center">Due Date</th>
<th>Communication</th>
<th class="text-right">Due</th>
<th class="text-right">Paid</th>
<th class="text-center">Litigation</th>
</tr>
</thead>
<tr t-foreach="Lines[o.id][currency]" t-as="line">
<td>
<span t-esc="line['move_id']"/>
</td>
<td>
<span t-esc="line['date']"/>
</td>
<td>
<span t-esc="line['date_maturity']"/>
</td>
<td>
<t t-if="line['name'] != '/'"><span t-esc="line['name']"/></t>
<span t-esc="line['ref']"/>
</td>
<td class="text-right">
<span t-esc="line['debit']" t-esc-options='{"widget": "monetary", "display_currency": "currency"}'/>
</td>
<td class="text-right">
<span t-esc="line['credit']" t-esc-options='{"widget": "monetary", "display_currency": "currency"}'/>
</td>
<td class="text-center">
<span t-if="line['blocked']">x</span>
</td>
</tr>
<tr>
<td colspan="3"></td>
<td><strong>Sub-Total :</strong></td>
<td class="text-right"><span t-esc="Totals[o.id][currency]['due']" t-esc-options='{"widget": "monetary", "display_currency": "currency"}'/></td>
<td class="text-right"><span t-esc="Totals[o.id][currency]['paid']" t-esc-options='{"widget": "monetary", "display_currency": "currency"}'/></td>
<td class="text-right"><span t-esc="Totals[o.id][currency]['mat']" t-esc-options='{"widget": "monetary", "display_currency": "currency"}'/></td>
<td></td>
</tr>
<tr>
<td colspan="3"></td>
<td><strong>Balance :</strong></td>
<td class="text-right">
<span t-esc="Totals[o.id][currency]['due'] - Totals[o.id][currency]['paid']" t-esc-options='{"widget": "monetary", "display_currency": "currency"}'/>
</td>
</tr>
</table>
</t>
<p t-if="not Lines[o.id]">
<strong>There is nothing due with this customer.</strong>
</p>
</div>
</div>
</t>
</template>
<template id="report_overdue">
<t t-call="report.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account.report_overdue_document" t-lang="o.lang"/>
</t>
</t>
</template>
</odoo>
@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_trialbalance">
<t t-call="report.html_container">
<t t-call="report.internal_layout">
<div class="page">
<h2><span t-esc="res_company.name"/>: Trial Balance</h2>
<div class="row mt32">
<div class="col-xs-4">
<strong>Display Account:</strong>
<p>
<span t-if="data['display_account'] == 'all'">All accounts</span>
<span t-if="data['display_account'] == 'movement'">With movements</span>
<span t-if="data['display_account'] == 'not_zero'">With balance not equal to zero</span>
</p>
</div>
<div class="col-xs-4">
<p>
<t t-if="data['date_from']"><strong>Date from :</strong> <span t-esc="data['date_from']"/><br/></t>
<t t-if="data['date_to']"><strong>Date to :</strong> <span t-esc="data['date_to']"/></t>
</p>
</div>
<div class="col-xs-4">
<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-condensed">
<thead>
<tr>
<th>Code</th>
<th>Account</th>
<th class="text-right">Debit</th>
<th class="text-right">Credit</th>
<th class="text-right">Balance</th>
</tr>
</thead>
<tbody>
<tr t-foreach="Accounts" t-as="account">
<td>
<span t-att-style="style" t-esc="account['code']"/>
</td>
<td>
<span style="color: white;" t-esc="'..'"/>
<span t-att-style="style" t-esc="account['name']"/>
</td>
<td class="text-right">
<span t-att-style="style" t-esc="account['debit']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-att-style="style" t-esc="account['credit']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
<td class="text-right">
<span t-att-style="style" t-esc="account['balance']" t-esc-options='{"widget": "monetary", "display_currency": "res_company.currency_id"}'/>
</td>
</tr>
</tbody>
</table>
</div>
</t>
</t>
</template>
</odoo>
+7
View File
@@ -9,3 +9,10 @@ import account_invoice_state
import account_validate_account_move
import pos_box
import account_move_reversal
import account_report_common
import account_report_common_account
import account_report_common_partner
import account_report_general_ledger
import account_report_trial_balance
import account_financial_report
import account_report_aged_partner_balance
@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models
class AccountingReport(models.TransientModel):
_name = "accounting.report"
_inherit = "account.common.report"
_description = "Accounting Report"
@api.model
def _get_account_report(self):
reports = []
if self._context.get('active_id'):
menu = self.env['ir.ui.menu'].browse(self._context.get('active_id')).name
reports = self.env['account.financial.report'].search([('name', 'ilike', menu)])
return reports and reports[0] or False
enable_filter = fields.Boolean(string='Enable Comparison')
account_report_id = fields.Many2one('account.financial.report', string='Account Reports', required=True, default=_get_account_report)
label_filter = fields.Char(string='Column Label', help="This label will be displayed on report to show the balance computed for the given comparison filter.")
filter_cmp = fields.Selection([('filter_no', 'No Filters'), ('filter_date', 'Date')], string='Filter by', required=True, default='filter_no')
date_from_cmp = fields.Date(string='Start Date')
date_to_cmp = fields.Date(string='End Date')
debit_credit = fields.Boolean(string='Display Debit/Credit Columns', help="This option allows you to get more details about the way your balances are computed. Because it is space consuming, we do not allow to use it while doing a comparison.")
def _build_comparison_context(self, data):
result = {}
result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
if data['form']['filter_cmp'] == 'filter_date':
result['date_from'] = data['form']['date_from_cmp']
result['date_to'] = data['form']['date_to_cmp']
result['strict_range'] = True
return result
@api.multi
def check_report(self):
res = super(AccountingReport, self).check_report()
data = {}
data['form'] = self.read(['account_report_id', 'date_from_cmp', 'date_to_cmp', 'journal_ids', 'filter_cmp', 'target_move'])[0]
for field in ['account_report_id']:
if isinstance(data['form'][field], tuple):
data['form'][field] = data['form'][field][0]
comparison_context = self._build_comparison_context(data)
res['data']['form']['comparison_context'] = comparison_context
return res
def _print_report(self, data):
data['form'].update(self.read(['date_from_cmp', 'debit_credit', 'date_to_cmp', 'filter_cmp', 'account_report_id', 'enable_filter', 'label_filter', 'target_move'])[0])
return self.env['report'].get_action(self, 'account.report_financial', data=data)
@@ -0,0 +1,72 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="accounting_report_view" model="ir.ui.view">
<field name="name">Accounting Report</field>
<field name="model">accounting.report</field>
<field name="inherit_id" ref="account.account_common_report_view"/>
<field name="arch" type="xml">
<field name="target_move" position="before">
<field name="account_report_id" domain="[('parent_id','=',False)]"/>
</field>
<field name="target_move" position="after">
<field name="enable_filter"/>
<field name="debit_credit" attrs="{'invisible': [('enable_filter','=',True)]}"/>
</field>
<field name="journal_ids" position="after">
<notebook tabpos="up" colspan="4">
<page string="Comparison" name="comparison" attrs="{'invisible': [('enable_filter','=',False)]}">
<group>
<field name="label_filter" attrs="{'required': [('enable_filter', '=', True)]}"/>
<field name="filter_cmp"/>
</group>
<group string="Dates" attrs="{'invisible':[('filter_cmp', '!=', 'filter_date')]}">
<field name="date_from_cmp" attrs="{'required':[('filter_cmp', '=', 'filter_date')]}"/>
<field name="date_to_cmp" attrs="{'required':[('filter_cmp', '=', 'filter_date')]}"/>
</group>
</page>
</notebook>
</field>
<field name="journal_ids" position="replace"/>
</field>
</record>
<record id="action_account_report_bs" model="ir.actions.act_window">
<field name="name">Balance Sheet</field>
<field name="res_model">accounting.report</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="accounting_report_view"/>
<field name="target">new</field>
<field name="context" eval="{'default_account_report_id':ref('account.account_financial_report_balancesheet0')}"/>
</record>
<menuitem id="menu_account_report_bs" name="Balance Sheet" action="action_account_report_bs" parent="menu_finance_legal_statement"/>
<record id="action_account_report_pl" model="ir.actions.act_window">
<field name="name">Profit and Loss</field>
<field name="res_model">accounting.report</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="accounting_report_view"/>
<field name="target">new</field>
<field name="context" eval="{'default_account_report_id':ref('account.account_financial_report_profitandloss0')}"/>
</record>
<menuitem id="menu_account_report_pl" name="Profit And Loss" action="action_account_report_pl" parent="menu_finance_legal_statement"/>
<record id="action_account_report" model="ir.actions.act_window">
<field name="name">Financial Reports</field>
<field name="res_model">accounting.report</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="accounting_report_view"/>
<field name="target">new</field>
</record>
<menuitem id="menu_account_report" name="Financial Report" action="action_account_report" parent="menu_finance_legal_statement" sequence="100"/>
</odoo>
@@ -0,0 +1,41 @@
# -*- coding: utf-8 -*-
import time
from datetime import datetime
from dateutil.relativedelta import relativedelta
from openerp import api, fields, models, _
from openerp.exceptions import UserError
class AccountAgedTrialBalance(models.TransientModel):
_name = 'account.aged.trial.balance'
_inherit = 'account.common.partner.report'
_description = 'Account Aged Trial balance Report'
period_length = fields.Integer(string='Period Length (days)', required=True, default=30)
journal_ids = fields.Many2many('account.journal', string='Journals', required=True)
date_from = fields.Date(default=lambda *a: time.strftime('%Y-%m-%d'))
def _print_report(self, data):
res = {}
data = self.pre_print_report(data)
data['form'].update(self.read(['period_length'])[0])
period_length = data['form']['period_length']
if period_length<=0:
raise UserError(_('You must set a period length greater than 0.'))
if not data['form']['date_from']:
raise UserError(_('You must set a start date.'))
start = datetime.strptime(data['form']['date_from'], "%Y-%m-%d")
for i in range(5)[::-1]:
stop = start - relativedelta(days=period_length)
res[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)
data['form'].update(res)
return self.env['report'].with_context(landscape=True).get_action(self, 'account.report_agedpartnerbalance', data=data)
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_aged_balance_view" model="ir.ui.view">
<field name="name">Aged Partner Balance</field>
<field name="model">account.aged.trial.balance</field>
<field name="arch" type="xml">
<form string="Report Options">
<separator string="Aged Partner Balance"/>
<label string="Aged Partner Balance is a more detailed report of your receivables by intervals. When opening that report, Odoo asks for the name of the company, the Start Date and the size of the interval to be analyzed (in days). Odoo then calculates a table of credit balance by start Date. So if you request an interval of 30 days Odoo generates an analysis of creditors for the past month, past two months, and so on. "/>
<group col="4">
<field name="date_from"/>
<field name="period_length"/>
<newline/>
<field name="result_selection" widget="radio"/>
<field name="target_move" widget="radio"/>
</group>
<field name="journal_ids" required="0" invisible="1"/>
<footer>
<button name="check_report" string="Print" type="object" default_focus="1" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel"/>
</footer>
</form>
</field>
</record>
<record id="action_account_aged_balance_view" model="ir.actions.act_window">
<field name="name">Aged Partner Balance</field>
<field name="res_model">account.aged.trial.balance</field>
<field name="type">ir.actions.act_window</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="view_id" ref="account_aged_balance_view"/>
<field name="context">{}</field>
<field name="target">new</field>
</record>
<menuitem id="menu_aged_trial_balance"
name="Aged Partner Balance"
action="action_account_aged_balance_view"
parent="account.menu_finance_legal_statement"/>
</odoo>
@@ -0,0 +1,39 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models, _
class AccountCommonReport(models.TransientModel):
_name = "account.common.report"
_description = "Account Common Report"
company_id = fields.Many2one('res.company', string='Company', readonly=True, default=lambda self: self.env.user.company_id)
journal_ids = fields.Many2many('account.journal', string='Journals', required=True, default=lambda self: self.env['account.journal'].search([]))
date_from = fields.Date(string='Start Date')
date_to = fields.Date(string='End Date')
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries'),
], string='Target Moves', required=True, default='posted')
def _build_contexts(self, data):
result = {}
result['journal_ids'] = 'journal_ids' in data['form'] and data['form']['journal_ids'] or False
result['state'] = 'target_move' in data['form'] and data['form']['target_move'] or ''
result['date_from'] = data['form']['date_from'] or False
result['date_to'] = data['form']['date_to'] or False
result['strict_range'] = True if result['date_from'] else False
return result
def _print_report(self, data):
raise (_('Error!'), _('Not implemented.'))
@api.multi
def check_report(self):
self.ensure_one()
data = {}
data['ids'] = self.env.context.get('active_ids', [])
data['model'] = self.env.context.get('active_model', 'ir.ui.menu')
data['form'] = self.read(['date_from', 'date_to', 'journal_ids', 'target_move'])[0]
used_context = self._build_contexts(data)
data['form']['used_context'] = dict(used_context, lang=self.env.context.get('lang', 'en_US'))
return self._print_report(data)
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from openerp import api, fields, models
class AccountCommonAccountReport(models.TransientModel):
_name = 'account.common.account.report'
_description = 'Account Common Account Report'
_inherit = "account.common.report"
display_account = fields.Selection([('all','All'), ('movement','With movements'),
('not_zero','With balance is not equal to 0'),],
string='Display Accounts', required=True, default='movement')
@api.multi
def pre_print_report(self, data):
data['form'].update(self.read(['display_account'])[0])
return data
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
from openerp import fields, models
class AccountingCommonPartnerReport(models.TransientModel):
_name = 'account.common.partner.report'
_description = 'Account Common Partner Report'
_inherit = "account.common.report"
result_selection = fields.Selection([('customer', 'Receivable Accounts'),
('supplier', 'Payable Accounts'),
('customer_supplier', 'Receivable and Payable Accounts')
], string="Partner's", required=True, default='customer')
def pre_print_report(self, data):
data['form'].update(self.read(['result_selection'])[0])
return data
@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_common_report_view" model="ir.ui.view">
<field name="name">Common Report</field>
<field name="model">account.common.report</field>
<field name="arch" type="xml">
<form string="Report Options">
<field name="company_id" invisible="1"/>
<group col="4">
<field name="target_move" widget="radio"/>
<field name="date_from"/>
<field name="date_to"/>
</group>
<group col="3">
<field name="journal_ids" widget="many2many_tags" options="{'no_create': True}"/>
</group>
<footer>
<button name="check_report" string="Print" type="object" default_focus="1" class="oe_highlight"/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<record id="action_account_common_menu" model="ir.actions.act_window">
<field name="name">Common Report</field>
<field name="res_model">account.common.report</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="account_common_report_view"/>
<field name="target">new</field>
</record>
</odoo>
@@ -0,0 +1,22 @@
# -*- coding: utf-8 -*-
from openerp import fields, models, _
from openerp.exceptions import UserError
class AccountReportGeneralLedger(models.TransientModel):
_inherit = "account.common.account.report"
_name = "account.report.general.ledger"
_description = "General Ledger Report"
initial_balance = fields.Boolean(string='Include Initial Balances',
help='If you selected date, this field allow you to add a row to display the amount of debit/credit/balance that precedes the filter you\'ve set.')
sortby = fields.Selection([('sort_date', 'Date'), ('sort_journal_partner', 'Journal & Partner')], string='Sort by', required=True, default='sort_date')
journal_ids = fields.Many2many('account.journal', 'account_report_general_ledger_journal_rel', 'account_id', 'journal_id', string='Journals', required=True)
def _print_report(self, data):
data = self.pre_print_report(data)
data['form'].update(self.read(['initial_balance', 'sortby'])[0])
if data['form'].get('initial_balance') and not data['form'].get('date_from'):
raise UserError(_("You must define a Start Date"))
return self.env['report'].with_context(landscape=True).get_action(self, 'account.report_generalledger', data=data)
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_report_general_ledger_view" model="ir.ui.view">
<field name="name">General Ledger</field>
<field name="model">account.report.general.ledger</field>
<field name="inherit_id" ref="account_common_report_view"/>
<field name="arch" type="xml">
<data>
<xpath expr="//field[@name='target_move']" position="after">
<field name="sortby" widget="radio"/>
<field name="display_account" widget="radio"/>
<field name="initial_balance"/>
<newline/>
</xpath>
</data>
</field>
</record>
<record id="action_account_general_ledger_menu" model="ir.actions.act_window">
<field name="name">General Ledger</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.report.general.ledger</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="account_report_general_ledger_view"/>
<field name="target">new</field>
</record>
<record id="action_account_general_ledger_values" model="ir.values">
<field name="model_id" ref="account.model_account_account" />
<field name="name">General Ledger</field>
<field name="key2">client_print_multi</field>
<field name="value" eval="'ir.actions.act_window,' +str(ref('action_account_general_ledger_menu'))" />
<field name="key">action</field>
<field name="model">account.account</field>
</record>
<menuitem
id="menu_general_ledger"
name="General Ledger"
parent="account.menu_finance_legal_statement"
action="action_account_general_ledger_menu"
groups="group_account_manager,group_account_user"
/>
</odoo>
@@ -0,0 +1,15 @@
# -*- coding: utf-8 -*-
from openerp import fields, models
class AccountBalanceReport(models.TransientModel):
_inherit = "account.common.account.report"
_name = 'account.balance.report'
_description = 'Trial Balance Report'
journal_ids = fields.Many2many('account.journal', 'account_balance_report_journal_rel', 'account_id', 'journal_id', string='Journals', required=True, default=[])
def _print_report(self, data):
data = self.pre_print_report(data)
return self.env['report'].get_action(self, 'account.report_trialbalance', data=data)
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="account_report_balance_view" model="ir.ui.view">
<field name="name">Trial Balance</field>
<field name="model">account.balance.report</field>
<field name="inherit_id" ref="account_common_report_view"/>
<field name="arch" type="xml">
<data>
<field name="journal_ids" position="replace"/>
<xpath expr="//field[@name='target_move']" position="after">
<field name="display_account" widget="radio"/>
<newline/>
</xpath>
</data>
</field>
</record>
<record id="action_account_balance_menu" model="ir.actions.act_window">
<field name="name">Trial Balance</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">account.balance.report</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="view_id" ref="account_report_balance_view"/>
<field name="target">new</field>
</record>
<menuitem id="menu_general_Balance_report"
name="Trial Balance"
parent="account.menu_finance_legal_statement"
action="action_account_balance_menu"/>
<record id="action_account_balance_report_values1" model="ir.values">
<field name="model_id" ref="account.model_account_account" />
<field name="name">Trial Balance</field>
<field name="key2">client_print_multi</field>
<field name="value" eval="'ir.actions.act_window,' +str(ref('action_account_balance_menu'))" />
<field name="key">action</field>
<field name="model">account.account</field>
</record>
</odoo>