Browse Source

[account_financial_report][IMP] Adds the following features, available in 11.0

- Introduce dependency with module account_group from OCA/account-financial-tools
All reports:
- Rename field to hide accounts at 0 to 'hide_account_at_0'
Trial Balance:
- Add hierarchy levels.
- Add possibility to filter by hierarchy levels
- XLSX format will show the hierarchy levels in bold

General Ledger:
- Add the possibility to filter by analytic tags
- Fixes an error on the default date
Journal Ledger:
- The filter on Journals is now optional. If the user does not choose
a journal, by default it will display all journals.

Aged Partner Balance:
- Fixes an error on the default date
pull/485/head
Jordi Ballester Alomar 6 years ago
parent
commit
0ed18d6c02
  1. 3
      account_financial_report_qweb/__manifest__.py
  2. 31
      account_financial_report_qweb/models/account_group.py
  3. 47
      account_financial_report_qweb/report/abstract_report_xlsx.py
  4. 356
      account_financial_report_qweb/report/general_ledger.py
  5. 2
      account_financial_report_qweb/report/general_ledger_xlsx.py
  6. 4
      account_financial_report_qweb/report/open_items.py
  7. 2
      account_financial_report_qweb/report/open_items_xlsx.py
  8. 4
      account_financial_report_qweb/report/templates/general_ledger.xml
  9. 4
      account_financial_report_qweb/report/templates/open_items.xml
  10. 182
      account_financial_report_qweb/report/templates/trial_balance.xml
  11. 290
      account_financial_report_qweb/report/trial_balance.py
  12. 19
      account_financial_report_qweb/report/trial_balance_xlsx.py
  13. 40
      account_financial_report_qweb/tests/test_general_ledger.py
  14. 4
      account_financial_report_qweb/tests/test_open_items.py
  15. 8
      account_financial_report_qweb/tests/test_trial_balance.py
  16. 3
      account_financial_report_qweb/wizard/aged_partner_balance_wizard.py
  17. 4
      account_financial_report_qweb/wizard/general_ledger_wizard.py
  18. 2
      account_financial_report_qweb/wizard/general_ledger_wizard_view.xml
  19. 9
      account_financial_report_qweb/wizard/journal_report_wizard.py
  20. 7
      account_financial_report_qweb/wizard/open_items_wizard.py
  21. 2
      account_financial_report_qweb/wizard/open_items_wizard_view.xml
  22. 48
      account_financial_report_qweb/wizard/trial_balance_wizard.py
  23. 5
      account_financial_report_qweb/wizard/trial_balance_wizard_view.xml

3
account_financial_report_qweb/__manifest__.py

@ -5,7 +5,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{ {
'name': 'QWeb Financial Reports', 'name': 'QWeb Financial Reports',
'version': '10.0.1.5.3',
'version': '10.0.2.0.0',
'category': 'Reporting', 'category': 'Reporting',
'summary': 'OCA Financial Reports', 'summary': 'OCA Financial Reports',
'author': 'Camptocamp SA,' 'author': 'Camptocamp SA,'
@ -16,6 +16,7 @@
"website": "https://odoo-community.org/", "website": "https://odoo-community.org/",
'depends': [ 'depends': [
'account', 'account',
'account_group', # account-financial-tools
'date_range', 'date_range',
'report_xlsx', 'report_xlsx',
'report', 'report',

31
account_financial_report_qweb/models/account_group.py

@ -0,0 +1,31 @@
# coding: utf-8
# Copyright 2018 Eficent
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
from odoo import api, fields, models
class AccountGroup(models.Model):
_inherit = 'account.group'
group_child_ids = fields.One2many(
comodel_name='account.group',
inverse_name='parent_id',
string='Child Groups')
compute_account_ids = fields.Many2many(
'account.account',
compute='_compute_group_accounts',
string="Accounts", store=True)
@api.multi
@api.depends('code_prefix', 'account_ids', 'account_ids.code',
'group_child_ids', 'group_child_ids.account_ids.code')
def _compute_group_accounts(self):
account_obj = self.env['account.account']
accounts = account_obj.search([])
for group in self:
prefix = group.code_prefix if group.code_prefix else group.name
gr_acc = accounts.filtered(
lambda a: a.code.startswith(prefix)).ids
group.compute_account_ids = [(6, 0, gr_acc)]

47
account_financial_report_qweb/report/abstract_report_xlsx.py

@ -23,6 +23,7 @@ class AbstractReportXslx(ReportXlsx):
# Formats # Formats
self.format_right = None self.format_right = None
self.format_left = None
self.format_right_bold_italic = None self.format_right_bold_italic = None
self.format_bold = None self.format_bold = None
self.format_header_left = None self.format_header_left = None
@ -43,6 +44,7 @@ class AbstractReportXslx(ReportXlsx):
self._define_formats(workbook) self._define_formats(workbook)
report_name = self._get_report_name() report_name = self._get_report_name()
report_footer = self._get_report_footer()
filters = self._get_report_filters(report) filters = self._get_report_filters(report)
self.columns = self._get_report_columns(report) self.columns = self._get_report_columns(report)
@ -57,6 +59,8 @@ class AbstractReportXslx(ReportXlsx):
self._generate_report_content(workbook, report) self._generate_report_content(workbook, report)
self._write_report_footer(report_footer)
def add_sheet(self, workbook, sheet_name): def add_sheet(self, workbook, sheet_name):
return workbook.add_worksheet(sheet_name) return workbook.add_worksheet(sheet_name)
@ -80,6 +84,7 @@ class AbstractReportXslx(ReportXlsx):
""" """
self.format_bold = workbook.add_format({'bold': True}) self.format_bold = workbook.add_format({'bold': True})
self.format_right = workbook.add_format({'align': 'right'}) self.format_right = workbook.add_format({'align': 'right'})
self.format_left = workbook.add_format({'align': 'left'})
self.format_right_bold_italic = workbook.add_format( self.format_right_bold_italic = workbook.add_format(
{'align': 'right', 'bold': True, 'italic': True} {'align': 'right', 'bold': True, 'italic': True}
) )
@ -107,6 +112,9 @@ class AbstractReportXslx(ReportXlsx):
self.format_amount = workbook.add_format() self.format_amount = workbook.add_format()
self.format_amount.set_num_format( self.format_amount.set_num_format(
'#,##0.'+'0'*currency_id.decimal_places) '#,##0.'+'0'*currency_id.decimal_places)
self.format_amount_bold = workbook.add_format({'bold': True})
self.format_amount_bold.set_num_format(
'#,##0.'+'0'*currency_id.decimal_places)
self.format_percent_bold_italic = workbook.add_format( self.format_percent_bold_italic = workbook.add_format(
{'bold': True, 'italic': True} {'bold': True, 'italic': True}
) )
@ -135,6 +143,18 @@ class AbstractReportXslx(ReportXlsx):
) )
self.row_pos += 3 self.row_pos += 3
def _write_report_footer(self, footer):
"""Write report footer .
Columns are defined with `_get_report_columns` method.
"""
if footer:
self.row_pos += 1
self.sheet.merge_range(
self.row_pos, 0, self.row_pos, len(self.columns) - 1,
footer, self.format_left
)
self.row_pos += 1
def _write_filters(self, filters): def _write_filters(self, filters):
"""Write one line per filters on starting on current line. """Write one line per filters on starting on current line.
Columns number for filter name is defined Columns number for filter name is defined
@ -188,10 +208,20 @@ class AbstractReportXslx(ReportXlsx):
value = getattr(line_object, column['field']) value = getattr(line_object, column['field'])
cell_type = column.get('type', 'string') cell_type = column.get('type', 'string')
if cell_type == 'string': if cell_type == 'string':
if hasattr(line_object, 'account_group_id') and \
line_object.account_group_id:
self.sheet.write_string(self.row_pos, col_pos, value or '',
self.format_bold)
else:
self.sheet.write_string(self.row_pos, col_pos, value or '') self.sheet.write_string(self.row_pos, col_pos, value or '')
elif cell_type == 'amount': elif cell_type == 'amount':
if hasattr(line_object, 'account_group_id') and \
line_object.account_group_id:
cell_format = self.format_amount_bold
else:
cell_format = self.format_amount
self.sheet.write_number( self.sheet.write_number(
self.row_pos, col_pos, float(value), self.format_amount
self.row_pos, col_pos, float(value), cell_format
) )
elif cell_type == 'amount_currency': elif cell_type == 'amount_currency':
if line_object.currency_id: if line_object.currency_id:
@ -288,10 +318,16 @@ class AbstractReportXslx(ReportXlsx):
def _get_currency_amt_format(self, line_object): def _get_currency_amt_format(self, line_object):
""" Return amount format specific for each currency. """ """ Return amount format specific for each currency. """
if hasattr(line_object, 'account_group_id') and \
line_object.account_group_id:
format_amt = getattr(self, 'format_amount_bold')
field_prefix = 'format_amount_bold'
else:
format_amt = getattr(self, 'format_amount') format_amt = getattr(self, 'format_amount')
field_prefix = 'format_amount'
if line_object.currency_id: if line_object.currency_id:
field_name = \ field_name = \
'format_amount_%s' % line_object.currency_id.name
'%s_%s' % (field_prefix, line_object.currency_id.name)
if hasattr(self, field_name): if hasattr(self, field_name):
format_amt = getattr(self, field_name) format_amt = getattr(self, field_name)
else: else:
@ -333,6 +369,13 @@ class AbstractReportXslx(ReportXlsx):
""" """
raise NotImplementedError() raise NotImplementedError()
def _get_report_footer(self):
"""
Allow to define the report footer.
:return: the report footer
"""
return False
def _get_report_columns(self, report): def _get_report_columns(self, report):
""" """
Allow to define the report columns Allow to define the report columns

356
account_financial_report_qweb/report/general_ledger.py

@ -29,7 +29,7 @@ class GeneralLedgerReport(models.TransientModel):
date_to = fields.Date() date_to = fields.Date()
fy_start_date = fields.Date() fy_start_date = fields.Date()
only_posted_moves = fields.Boolean() only_posted_moves = fields.Boolean()
hide_account_balance_at_0 = fields.Boolean()
hide_account_at_0 = fields.Boolean()
foreign_currency = fields.Boolean() foreign_currency = fields.Boolean()
show_analytic_tags = fields.Boolean() show_analytic_tags = fields.Boolean()
company_id = fields.Many2one(comodel_name='res.company') company_id = fields.Many2one(comodel_name='res.company')
@ -552,7 +552,7 @@ WHERE
OR f.balance IS NOT NULL AND f.balance != 0 OR f.balance IS NOT NULL AND f.balance != 0
) )
""" """
if self.hide_account_balance_at_0:
if self.hide_account_at_0:
query_inject_account += """ query_inject_account += """
AND AND
f.balance IS NOT NULL AND f.balance != 0 f.balance IS NOT NULL AND f.balance != 0
@ -613,7 +613,7 @@ AND
tuple(self.filter_cost_center_ids.ids), tuple(self.filter_cost_center_ids.ids),
) )
query_inject_account_params += ( query_inject_account_params += (
self.id or 'NULL',
self.id,
self.env.uid, self.env.uid,
) )
self.env.cr.execute(query_inject_account, query_inject_account_params) self.env.cr.execute(query_inject_account, query_inject_account_params)
@ -934,7 +934,7 @@ WHERE
OR f.balance IS NOT NULL AND f.balance != 0 OR f.balance IS NOT NULL AND f.balance != 0
) )
""" """
if self.hide_account_balance_at_0:
if self.hide_account_at_0:
query_inject_partner += """ query_inject_partner += """
AND AND
f.balance IS NOT NULL AND f.balance != 0 f.balance IS NOT NULL AND f.balance != 0
@ -1559,158 +1559,160 @@ WHERE
} }
self.env.cr.execute(query_update_analytic_tags, params) self.env.cr.execute(query_update_analytic_tags, params)
def _get_unaffected_earnings_account_sub_subquery_sum_initial(
self
):
""" Return subquery used to compute sum amounts on
unaffected earnings accounts """
sub_subquery_sum_amounts = """
def _inject_unaffected_earnings_account_values(self):
"""Inject the report values of the unaffected earnings account
for report_general_ledger_qweb_account."""
# Fetch the profit and loss accounts
query_unaffected_earnings_account_ids = """
SELECT a.id
FROM account_account as a
INNER JOIN account_account_type as at
ON at.id = a.user_type_id
WHERE at.include_initial_balance = FALSE
"""
self.env.cr.execute(query_unaffected_earnings_account_ids)
pl_account_ids = [r[0] for r in self.env.cr.fetchall()]
unaffected_earnings_account_ids = \
pl_account_ids + [self.unaffected_earnings_account.id]
# Fetch the current fiscal year start date
date = fields.Datetime.from_string(self.date_from)
res = self.company_id.compute_fiscalyear_dates(date)
fy_start_date = res['date_from']
query_select_previous_fy_unaffected_earnings_params = {
'date_to': fy_start_date,
'company_id': self.company_id.id,
'account_ids': tuple(unaffected_earnings_account_ids),
'analytic_tag_ids': tuple(self.filter_analytic_tag_ids.ids),
}
query_select_previous_fy_unaffected_earnings = ''
q_analytic_tags = ''
if self.filter_analytic_tag_ids:
q_analytic_tags = """
WITH move_lines_on_tags AS
(
SELECT SELECT
SUM(ml.balance) AS initial_balance,
0.0 AS final_balance
DISTINCT ml.id AS ml_id
FROM FROM
account_account a account_account a
INNER JOIN
account_account_type at ON a.user_type_id = at.id
INNER JOIN INNER JOIN
account_move_line ml account_move_line ml
ON a.id = ml.account_id ON a.id = ml.account_id
AND ml.date < %(date_from)s
"""
if self.only_posted_moves:
sub_subquery_sum_amounts += """
INNER JOIN INNER JOIN
account_move m ON ml.move_id = m.id AND m.state = 'posted'
"""
if self.filter_cost_center_ids:
sub_subquery_sum_amounts += """
account_analytic_tag_account_move_line_rel atml
ON atml.account_move_line_id = ml.id
INNER JOIN INNER JOIN
account_analytic_account aa
account_analytic_tag aat
ON ON
ml.analytic_account_id = aa.id
atml.account_analytic_tag_id = aat.id
WHERE
aat.id IN %(analytic_tag_ids)s
)
"""
query_select_previous_fy_unaffected_earnings += q_analytic_tags
query_select_previous_fy_unaffected_earnings += """
SELECT sum(ml.balance) as balance
FROM account_move_line as ml
INNER JOIN account_move as am
ON am.id = ml.move_id
INNER JOIN account_journal j
ON am.journal_id = j.id
"""
if self.filter_cost_center_ids:
query_select_previous_fy_unaffected_earnings += """
INNER JOIN account_analytic_account aa
ON aml.analytic_account_id = aa.id
AND aa.id IN %(cost_center_ids)s AND aa.id IN %(cost_center_ids)s
""" """
query_select_previous_fy_unaffected_earnings_params[
'cost_center_ids'] = tuple(self.filter_cost_center_ids.ids)
if self.filter_analytic_tag_ids: if self.filter_analytic_tag_ids:
sub_subquery_sum_amounts += """
INNER JOIN
move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id
query_select_previous_fy_unaffected_earnings += """
INNER JOIN move_lines_on_tags ON ml.id =
move_lines_on_tags.ml_id
""" """
sub_subquery_sum_amounts += """
WHERE
a.company_id = %(company_id)s
AND
a.id IN %(unaffected_earnings_account_ids)s
query_select_previous_fy_unaffected_earnings += """
WHERE ml.date < %(date_to)s
AND ml.company_id = %(company_id)s
AND ml.account_id IN %(account_ids)s
""" """
if self.filter_journal_ids: if self.filter_journal_ids:
sub_subquery_sum_amounts += """
AND
ml.journal_id in %(filter_journal_ids)s """
return sub_subquery_sum_amounts
def _get_unaffected_earnings_account_sub_subquery_sum_final(self):
""" Return subquery used to compute sum amounts on
unaffected earnings accounts """
sub_subquery_sum_amounts = """
SELECT
0.0 AS initial_balance,
SUM(ml.balance) AS final_balance
"""
sub_subquery_sum_amounts += """
FROM
account_account a
INNER JOIN
account_account_type at ON a.user_type_id = at.id
INNER JOIN
account_move_line ml
ON a.id = ml.account_id
AND ml.date <= %(date_to)s
query_select_previous_fy_unaffected_earnings += """
AND j.id IN %(journal_ids)s
""" """
query_select_previous_fy_unaffected_earnings_params[
'journal_ids'] = tuple(self.filter_journal_ids.ids)
if self.only_posted_moves: if self.only_posted_moves:
sub_subquery_sum_amounts += """
INNER JOIN
account_move m ON ml.move_id = m.id AND m.state = 'posted'
query_select_previous_fy_unaffected_earnings += """
AND am.state = 'posted'
"""
self.env.cr.execute(
query_select_previous_fy_unaffected_earnings,
query_select_previous_fy_unaffected_earnings_params)
res = self.env.cr.fetchone()
unaffected_earnings_initial_balance = res[0] or 0.0
# Now select the current period unaffected earnings,
# excluding the current period P&L.
query_select_period_unaffected_earnings_params = {
'date_from': self.date_from,
'date_to': self.date_to,
'company_id': self.company_id.id,
'unaffected_earnings_id': self.unaffected_earnings_account.id,
'analytic_tag_ids': tuple(self.filter_analytic_tag_ids.ids),
}
query_select_period_unaffected_earnings = ''
if self.filter_analytic_tag_ids:
query_select_period_unaffected_earnings += q_analytic_tags
query_select_period_unaffected_earnings += """
SELECT
sum(ml.debit) as sum_debit,
sum(ml.credit) as sum_credit,
sum(ml.balance) as balance
FROM account_move_line as ml
INNER JOIN account_move as am
ON am.id = ml.move_id
INNER JOIN account_journal j
ON am.journal_id = j.id
""" """
if self.filter_cost_center_ids: if self.filter_cost_center_ids:
sub_subquery_sum_amounts += """
INNER JOIN
account_analytic_account aa
ON
ml.analytic_account_id = aa.id
query_select_period_unaffected_earnings += """
INNER JOIN account_analytic_account aa
ON aml.analytic_account_id = aa.id
AND aa.id IN %(cost_center_ids)s AND aa.id IN %(cost_center_ids)s
""" """
query_select_period_unaffected_earnings_params[
'cost_center_ids'] = tuple(self.filter_cost_center_ids.ids)
if self.filter_analytic_tag_ids: if self.filter_analytic_tag_ids:
sub_subquery_sum_amounts += """
INNER JOIN
move_lines_on_tags ON ml.id = move_lines_on_tags.ml_id
query_select_period_unaffected_earnings += """
INNER JOIN move_lines_on_tags
ON ml.id = move_lines_on_tags.ml_id
""" """
sub_subquery_sum_amounts += """
WHERE
a.company_id = %(company_id)s
AND
a.id IN %(unaffected_earnings_account_ids)s
query_select_period_unaffected_earnings += """
WHERE am.date >= %(date_from)s
AND ml.date <= %(date_to)s
AND ml.company_id = %(company_id)s
AND ml.account_id = %(unaffected_earnings_id)s
""" """
if self.filter_journal_ids: if self.filter_journal_ids:
sub_subquery_sum_amounts += """
AND
ml.journal_id in %(filter_journal_ids)s
"""
return sub_subquery_sum_amounts
def _inject_unaffected_earnings_account_values(self):
"""Inject the report values of the unaffected earnings account
for report_general_ledger_qweb_account."""
subquery_sum_amounts = """
SELECT
SUM(COALESCE(sub.initial_balance, 0.0)) AS initial_balance,
SUM(COALESCE(sub.final_balance, 0.0)) AS final_balance
FROM
(
"""
# Initial balances
subquery_sum_amounts += \
self._get_unaffected_earnings_account_sub_subquery_sum_initial()
subquery_sum_amounts += """
UNION
"""
subquery_sum_amounts += \
self._get_unaffected_earnings_account_sub_subquery_sum_final()
subquery_sum_amounts += """
) sub
query_select_period_unaffected_earnings += """
AND j.id IN %(journal_ids)s
""" """
query_select_period_unaffected_earnings_params[
'journal_ids'] = tuple(self.filter_journal_ids.ids)
if self.only_posted_moves:
query_select_period_unaffected_earnings += """
AND am.state = 'posted'
"""
self.env.cr.execute(query_select_period_unaffected_earnings,
query_select_period_unaffected_earnings_params)
res = self.env.cr.fetchone()
unaffected_earnings_period_debit = res[0] or 0.0
unaffected_earnings_period_credit = res[1] or 0.0
unaffected_earnings_period_balance = res[2] or 0.0
# pylint: disable=sql-injection # pylint: disable=sql-injection
query_inject_account = """ query_inject_account = """
WITH
"""
if self.filter_analytic_tag_ids:
query_inject_account += """
move_lines_on_tags AS
(
SELECT
DISTINCT ml.id AS ml_id
FROM
account_account a
INNER JOIN
account_move_line ml
ON a.id = ml.account_id
INNER JOIN
account_analytic_tag_account_move_line_rel atml
ON atml.account_move_line_id = ml.id
INNER JOIN
account_analytic_tag aat
ON
atml.account_analytic_tag_id = aat.id
WHERE
aat.id IN %(analytic_tag_ids)s
),
"""
query_inject_account += """
sum_amounts AS ( """ + subquery_sum_amounts + """ )
INSERT INTO INSERT INTO
report_general_ledger_qweb_account
(
report_general_ledger_qweb_account (
report_id, report_id,
create_uid, create_uid,
create_date, create_date,
@ -1718,65 +1720,47 @@ WHERE
code, code,
name, name,
is_partner_account, is_partner_account,
initial_debit,
initial_credit,
initial_balance, initial_balance,
final_balance,
currency_id
)
SELECT
%(report_id)s AS report_id,
%(user_id)s AS create_uid,
NOW() AS create_date,
a.id AS account_id,
a.code,
a.name,
False AS is_partner_account,
COALESCE(i.initial_balance, 0.0) AS initial_balance,
COALESCE(i.final_balance, 0.0) AS final_balance,
c.id as currency_id
FROM
account_account a
LEFT JOIN
res_currency c ON c.id = a.currency_id,
sum_amounts i
WHERE
a.company_id = %(company_id)s
AND a.id = %(unaffected_earnings_account_id)s
"""
query_inject_account_params = {}
if self.filter_analytic_tag_ids:
query_inject_account_params['analytic_tag_ids'] = \
tuple(self.filter_analytic_tag_ids.ids)
query_inject_account_params.update({
'date_from': self.date_from,
'date_to': self.date_to,
'fy_start_date': self.fy_start_date,
})
if self.filter_cost_center_ids:
query_inject_account_params['cost_center_ids'] = \
tuple(self.filter_cost_center_ids.ids)
query_inject_account_params['company_id'] = self.company_id.id
query_inject_account_params['unaffected_earnings_account_id'] = \
self.unaffected_earnings_account.id
query_inject_account_params['report_id'] = self.id
query_inject_account_params['user_id'] = self.env.uid
if self.filter_journal_ids:
query_inject_account_params['filter_journal_ids'] = (tuple(
self.filter_journal_ids.ids,
),)
# Fetch the profit and loss accounts
query_unaffected_earnings_account_ids = """
SELECT a.id
FROM account_account as a
INNER JOIN account_account_type as at
ON at.id = a.user_type_id
WHERE at.include_initial_balance = FALSE
"""
self.env.cr.execute(query_unaffected_earnings_account_ids)
pl_account_ids = [r[0] for r in self.env.cr.fetchall()]
query_inject_account_params['unaffected_earnings_account_ids'] = \
tuple(pl_account_ids + [self.unaffected_earnings_account.id])
final_debit,
final_credit,
final_balance
)
VALUES (
%(report_id)s,
%(user_id)s,
NOW(),
%(account_id)s,
%(code)s,
%(name)s,
False,
%(initial_debit)s,
%(initial_credit)s,
%(initial_balance)s,
%(final_debit)s,
%(final_credit)s,
%(final_balance)s
)
"""
initial_debit = unaffected_earnings_initial_balance >= 0 and \
unaffected_earnings_initial_balance or 0
initial_credit = unaffected_earnings_initial_balance < 0 and \
-1 * unaffected_earnings_initial_balance or 0
final_balance = unaffected_earnings_initial_balance + \
unaffected_earnings_period_balance
query_inject_account_params = {
'report_id': self.id,
'user_id': self.env.uid,
'account_id': self.unaffected_earnings_account.id,
'code': self.unaffected_earnings_account.code,
'name': self.unaffected_earnings_account.name,
'initial_debit': initial_debit,
'initial_credit': initial_credit,
'initial_balance': unaffected_earnings_initial_balance,
'final_debit': initial_debit + unaffected_earnings_period_debit,
'final_credit': initial_credit + unaffected_earnings_period_credit,
'final_balance': final_balance,
}
self.env.cr.execute(query_inject_account, self.env.cr.execute(query_inject_account,
query_inject_account_params) query_inject_account_params)

2
account_financial_report_qweb/report/general_ledger_xlsx.py

@ -89,7 +89,7 @@ class GeneralLedgerXslx(abstract_report_xlsx.AbstractReportXslx):
], ],
[ [
_('Account balance at 0 filter'), _('Account balance at 0 filter'),
_('Hide') if report.hide_account_balance_at_0 else _('Show'),
_('Hide') if report.hide_account_at_0 else _('Show'),
], ],
[ [
_('Centralize filter'), _('Centralize filter'),

4
account_financial_report_qweb/report/open_items.py

@ -22,7 +22,7 @@ class OpenItemsReport(models.TransientModel):
# Filters fields, used for data computation # Filters fields, used for data computation
date_at = fields.Date() date_at = fields.Date()
only_posted_moves = fields.Boolean() only_posted_moves = fields.Boolean()
hide_account_balance_at_0 = fields.Boolean()
hide_account_at_0 = fields.Boolean()
foreign_currency = fields.Boolean() foreign_currency = fields.Boolean()
company_id = fields.Many2one(comodel_name='res.company') company_id = fields.Many2one(comodel_name='res.company')
filter_account_ids = fields.Many2many(comodel_name='account.account') filter_account_ids = fields.Many2many(comodel_name='account.account')
@ -188,7 +188,7 @@ class OpenItemsReportCompute(models.TransientModel):
self._inject_line_values(only_empty_partner_line=True) self._inject_line_values(only_empty_partner_line=True)
self._clean_partners_and_accounts() self._clean_partners_and_accounts()
self._compute_partners_and_accounts_cumul() self._compute_partners_and_accounts_cumul()
if self.hide_account_balance_at_0:
if self.hide_account_at_0:
self._clean_partners_and_accounts( self._clean_partners_and_accounts(
only_delete_account_balance_at_0=True only_delete_account_balance_at_0=True
) )

2
account_financial_report_qweb/report/open_items_xlsx.py

@ -63,7 +63,7 @@ class OpenItemsXslx(abstract_report_xlsx.AbstractReportXslx):
_('All posted entries') if report.only_posted_moves else _( _('All posted entries') if report.only_posted_moves else _(
'All entries')], 'All entries')],
[_('Account balance at 0 filter'), [_('Account balance at 0 filter'),
_('Hide') if report.hide_account_balance_at_0 else _('Show')],
_('Hide') if report.hide_account_at_0 else _('Show')],
[_('Show foreign currency'), [_('Show foreign currency'),
_('Yes') if report.foreign_currency else _('No')], _('Yes') if report.foreign_currency else _('No')],
] ]

4
account_financial_report_qweb/report/templates/general_ledger.xml

@ -93,8 +93,8 @@
<t t-if="not o.only_posted_moves">All entries</t> <t t-if="not o.only_posted_moves">All entries</t>
</div> </div>
<div class="act_as_cell"> <div class="act_as_cell">
<t t-if="o.hide_account_balance_at_0">Hide</t>
<t t-if="not o.hide_account_balance_at_0">Show</t>
<t t-if="o.hide_account_at_0">Hide</t>
<t t-if="not o.hide_account_at_0">Show</t>
</div> </div>
<div class="act_as_cell"> <div class="act_as_cell">
<t t-if="o.centralize">Yes</t> <t t-if="o.centralize">Yes</t>

4
account_financial_report_qweb/report/templates/open_items.xml

@ -75,8 +75,8 @@
<t t-if="not o.only_posted_moves">All entries</t> <t t-if="not o.only_posted_moves">All entries</t>
</div> </div>
<div class="act_as_cell"> <div class="act_as_cell">
<t t-if="o.hide_account_balance_at_0">Hide</t>
<t t-if="not o.hide_account_balance_at_0">Show</t>
<t t-if="o.hide_account_at_0">Hide</t>
<t t-if="not o.hide_account_at_0">Show</t>
</div> </div>
</div> </div>
</div> </div>

182
account_financial_report_qweb/report/templates/trial_balance.xml

@ -27,20 +27,29 @@
<!-- Display account lines --> <!-- Display account lines -->
<t t-if="not show_partner_details"> <t t-if="not show_partner_details">
<div class="act_as_table data_table" style="width: 1325px !important;">
<div class="act_as_table data_table" style="width: 100%;">
<!-- Display account header --> <!-- Display account header -->
<t t-call="account_financial_report_qweb.report_trial_balance_qweb_lines_header"/> <t t-call="account_financial_report_qweb.report_trial_balance_qweb_lines_header"/>
<!-- Display each lines --> <!-- Display each lines -->
<t t-foreach="o.account_ids" t-as="line">
<t t-foreach="o.account_ids.filtered(lambda a: not a.hide_line)" t-as="line">
<t t-set="type" t-value='"account_type"'/> <t t-set="type" t-value='"account_type"'/>
<!-- Adapt --> <!-- Adapt -->
<t t-set="style" t-value="'font-size:8px;'"/> <t t-set="style" t-value="'font-size:8px;'"/>
<t t-set="padding" t-value="line.level * 4"/> <t t-set="padding" t-value="line.level * 4"/>
<t t-if="o.hide_account_at_0">
<t t-set="style" t-value="'font-size: 14px;'"/>
</t>
<t t-if="o.hierarchy_on != 'none'">
<t t-set="style" t-value="'font-size: ' + str(14 - line.level) + 'px; margin-left: ' + str(line.level * 4) + 'px;'"/> <t t-set="style" t-value="'font-size: ' + str(14 - line.level) + 'px; margin-left: ' + str(line.level * 4) + 'px;'"/>
</t>
<t t-if="line.account_group_id">
<t t-set="style" t-value="style + 'font-weight: bold; color: blue;'"/>
</t>
<!-- Display account lines --> <!-- Display account lines -->
<t t-call="account_financial_report_qweb.report_trial_balance_qweb_line"/> <t t-call="account_financial_report_qweb.report_trial_balance_qweb_line"/>
<!-- Adapt style -->
</t> </t>
</div> </div>
</t> </t>
@ -94,13 +103,13 @@
</t> </t>
</div> </div>
</template> </template>
<template id="account_financial_report_qweb.report_trial_balance_qweb_filters"> <template id="account_financial_report_qweb.report_trial_balance_qweb_filters">
<div class="act_as_table data_table" style="width: 100%;"> <div class="act_as_table data_table" style="width: 100%;">
<div class="act_as_row labels"> <div class="act_as_row labels">
<div class="act_as_cell">Date range filter</div> <div class="act_as_cell">Date range filter</div>
<div class="act_as_cell">Target moves filter</div> <div class="act_as_cell">Target moves filter</div>
<div class="act_as_cell">Account balance at 0 filter</div> <div class="act_as_cell">Account balance at 0 filter</div>
<div class="act_as_cell">Limit hierarchy levels</div>
</div> </div>
<div class="act_as_row"> <div class="act_as_row">
<div class="act_as_cell"> <div class="act_as_cell">
@ -111,8 +120,16 @@
<t t-if="not o.only_posted_moves">All entries</t> <t t-if="not o.only_posted_moves">All entries</t>
</div> </div>
<div class="act_as_cell"> <div class="act_as_cell">
<t t-if="o.hide_account_balance_at_0">Hide</t>
<t t-if="not o.hide_account_balance_at_0">Show</t>
<t t-if="o.hide_account_at_0">Hide</t>
<t t-if="not o.hide_account_at_0">Show</t>
</div>
<div class="act_as_cell">
<t t-if="o.limit_hierarchy_level">
Level <span t-field="o.show_hierarchy_level"/>
</t>
<t t-if="not o.limit_hierarchy_level">
No limit
</t>
</div> </div>
</div> </div>
</div> </div>
@ -141,6 +158,8 @@
<div class="act_as_cell" style="width: 9.64%;">Debit</div> <div class="act_as_cell" style="width: 9.64%;">Debit</div>
<!--## Credit--> <!--## Credit-->
<div class="act_as_cell" style="width: 9.64%;">Credit</div> <div class="act_as_cell" style="width: 9.64%;">Credit</div>
<!--## Period balance-->
<div class="act_as_cell" style="width: 9.64%;">Period balance</div>
<!--## Ending balance--> <!--## Ending balance-->
<div class="act_as_cell" style="width: 9.64%;">Ending balance</div> <div class="act_as_cell" style="width: 9.64%;">Ending balance</div>
<t t-if="foreign_currency"> <t t-if="foreign_currency">
@ -170,6 +189,16 @@
<t t-att-style="style" t-raw="line.code"/></a> <t t-att-style="style" t-raw="line.code"/></a>
</span> </span>
</t> </t>
<t t-if="line.account_group_id">
<t t-set="res_model" t-value="'account.group'"/>
<span>
<a t-att-data-active-id="line.account_group_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
t-att-style="style">
<t t-att-style="style" t-raw="line.code"/></a>
</span>
</t>
</div> </div>
</t> </t>
<!--## Account/Partner--> <!--## Account/Partner-->
@ -186,6 +215,16 @@
<t t-att-style="style" t-raw="line.name"/></a> <t t-att-style="style" t-raw="line.name"/></a>
</span> </span>
</t> </t>
<t t-if="line.account_group_id">
<t t-set="res_model" t-value="'account.group'"/>
<span>
<a t-att-data-active-id="line.account_group_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
t-att-style="style">
<t t-att-style="style" t-raw="line.name"/></a>
</span>
</t>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="account_or_partner_line" t-value="line.report_account_id"/> <t t-set="account_or_partner_line" t-value="line.report_account_id"/>
@ -214,6 +253,18 @@
<t t-att-style="style" t-raw="line.initial_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a> <t t-att-style="style" t-raw="line.initial_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span> </span>
</t> </t>
<t t-if="line.account_group_id">
<t t-set="domain"
t-value="[('account_id', 'in', line.compute_account_ids.ids),
('date', '&lt;', o.date_from)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.initial_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <t t-set="domain"
@ -246,6 +297,20 @@
<t t-att-style="style" t-raw="line.debit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a> <t t-att-style="style" t-raw="line.debit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span> </span>
</t> </t>
<t t-if="line.account_group_id">
<t t-set="domain"
t-value="[('account_id', 'in', line.compute_account_ids.ids),
('date', '&gt;=', line.report_id.date_from),
('date', '&lt;=', line.report_id.date_to),
('debit', '&lt;&gt;', 0)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.debit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <t t-set="domain"
@ -280,6 +345,20 @@
<t t-att-style="style" t-raw="line.credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a> <t t-att-style="style" t-raw="line.credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span> </span>
</t> </t>
<t t-if="line.account_group_id">
<t t-set="domain"
t-value="[('account_id', 'in', line.compute_account_ids.ids),
('date', '&gt;=', line.report_id.date_from),
('date', '&lt;=', line.report_id.date_to),
('credit', '&lt;&gt;', 0)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <t t-set="domain"
@ -297,6 +376,51 @@
</span> </span>
</t> </t>
</div> </div>
<!--## Period balance-->
<div class="act_as_cell amount">
<t t-if="type == 'account_type'">
<t t-if="line.account_id">
<t t-set="domain"
t-value="[('account_id', '=', line.account_id.id),
('date', '&gt;=', line.report_id.date_from),
('date', '&lt;=', line.report_id.date_to)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.period_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="line.account_group_id">
<t t-set="domain"
t-value="[('account_id', 'in', line.compute_account_ids.ids),
('date', '&gt;=', line.report_id.date_from),
('date', '&lt;=', line.report_id.date_to)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.period_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</t>
<t t-if="type == 'partner_type'">
<t t-set="domain"
t-value="[('account_id', '=', line.report_account_id.account_id.id),
('partner_id', '=', line.partner_id.id),
('date', '&gt;=', line.report_account_id.report_id.date_from),
('date', '&lt;=', line.report_account_id.report_id.date_to)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.period_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</div>
<!--## Ending balance--> <!--## Ending balance-->
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<t t-if="type == 'account_type'"> <t t-if="type == 'account_type'">
@ -311,6 +435,17 @@
<t t-att-style="style" t-raw="line.final_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a> <t t-att-style="style" t-raw="line.final_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span> </span>
</t> </t>
<t t-if="line.account_group_id">
<t t-set="domain"
t-value="[('account_id', 'in', line.compute_account_ids.ids)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.final_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <t t-set="domain"
@ -345,6 +480,17 @@
<t t-att-style="style" t-raw="line.initial_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/></a> <t t-att-style="style" t-raw="line.initial_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/></a>
</span> </span>
</t> </t>
<t t-if="line.account_group_id">
<t t-set="domain"
t-value="[('account_id', 'in', line.compute_account_ids.ids)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.initial_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/></a>
</span>
</t>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <t t-set="domain"
@ -373,6 +519,17 @@
<t t-att-style="style" t-raw="line.final_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/></a> <t t-att-style="style" t-raw="line.final_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/></a>
</span> </span>
</t> </t>
<t t-if="line.account_group_id">
<t t-set="domain"
t-value="[('account_id', 'in', line.compute_account_ids.ids)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
t-att-style="style">
<t t-att-style="style" t-raw="line.final_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/></a>
</span>
</t>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <t t-set="domain"
@ -456,6 +613,21 @@
<t t-att-style="style" t-raw="account.credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a> <t t-att-style="style" t-raw="account.credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span> </span>
</div> </div>
<!--## Period Balance -->
<div class="act_as_cell amount" style="width: 9.64%;">
<t t-set="domain"
t-value="[('account_id', '=', account.account_id.id),
('date', '&gt;=', account.report_id.date_from),
('date', '&lt;=', account.report_id.date_to),
('period_balance', '&lt;&gt;', 0)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
t-att-style="style">
<t t-att-style="style" t-raw="account.period_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</div>
<!--## Ending balance--> <!--## Ending balance-->
<div class="act_as_cell amount" style="width: 9.64%;"> <div class="act_as_cell amount" style="width: 9.64%;">
<t t-set="domain" <t t-set="domain"

290
account_financial_report_qweb/report/trial_balance.py

@ -24,14 +24,29 @@ class TrialBalanceReport(models.TransientModel):
date_to = fields.Date() date_to = fields.Date()
fy_start_date = fields.Date() fy_start_date = fields.Date()
only_posted_moves = fields.Boolean() only_posted_moves = fields.Boolean()
hide_account_balance_at_0 = fields.Boolean()
hide_account_at_0 = fields.Boolean()
foreign_currency = fields.Boolean() foreign_currency = fields.Boolean()
company_id = fields.Many2one(comodel_name='res.company') company_id = fields.Many2one(comodel_name='res.company')
filter_account_ids = fields.Many2many(comodel_name='account.account') filter_account_ids = fields.Many2many(comodel_name='account.account')
filter_partner_ids = fields.Many2many(comodel_name='res.partner') filter_partner_ids = fields.Many2many(comodel_name='res.partner')
filter_journal_ids = fields.Many2many(comodel_name='account.journal') filter_journal_ids = fields.Many2many(comodel_name='account.journal')
show_partner_details = fields.Boolean() show_partner_details = fields.Boolean()
hierarchy_on = fields.Selection(
[('computed', 'Computed Accounts'),
('relation', 'Child Accounts'),
('none', 'No hierarchy')],
string='Hierarchy On',
required=True,
default='computed',
help="""Computed Accounts: Use when the account group have codes
that represent prefixes of the actual accounts.\n
Child Accounts: Use when your account groups are hierarchical.\n
No hierarchy: Use to display just the accounts, without any grouping.
""", period_balance=fields.Float(digits=(16, 2))
)
limit_hierarchy_level = fields.Boolean('Limit hierarchy levels')
show_hierarchy_level = fields.Integer('Hierarchy Levels to display',
default=1)
# General Ledger Report Data fields, # General Ledger Report Data fields,
# used as base for compute the data reports # used as base for compute the data reports
general_ledger_id = fields.Many2one( general_ledger_id = fields.Many2one(
@ -49,17 +64,17 @@ class TrialBalanceReportAccount(models.TransientModel):
_name = 'report_trial_balance_qweb_account' _name = 'report_trial_balance_qweb_account'
_inherit = 'report_qweb_abstract' _inherit = 'report_qweb_abstract'
_order = 'code ASC'
_order = 'sequence, code ASC, name'
report_id = fields.Many2one( report_id = fields.Many2one(
comodel_name='report_trial_balance_qweb', comodel_name='report_trial_balance_qweb',
ondelete='cascade', ondelete='cascade',
index=True index=True
) )
hide_line = fields.Boolean(compute='_compute_hide_line')
# Data fields, used to keep link with real object # Data fields, used to keep link with real object
sequence = fields.Integer(index=True, default=0)
level = fields.Integer(index=True, default=0)
sequence = fields.Integer(index=True, default=1)
level = fields.Integer(index=True, default=1)
# Data fields, used to keep link with real object # Data fields, used to keep link with real object
account_id = fields.Many2one( account_id = fields.Many2one(
@ -67,6 +82,20 @@ class TrialBalanceReportAccount(models.TransientModel):
index=True index=True
) )
account_group_id = fields.Many2one(
'account.group',
index=True
)
parent_id = fields.Many2one(
'account.group',
index=True
)
child_account_ids = fields.Char(
string="Accounts")
compute_account_ids = fields.Many2many(
'account.account',
string="Accounts", store=True)
# Data fields, used for report display # Data fields, used for report display
code = fields.Char() code = fields.Char()
name = fields.Char() name = fields.Char()
@ -75,6 +104,7 @@ class TrialBalanceReportAccount(models.TransientModel):
initial_balance_foreign_currency = fields.Float(digits=(16, 2)) initial_balance_foreign_currency = fields.Float(digits=(16, 2))
debit = fields.Float(digits=(16, 2)) debit = fields.Float(digits=(16, 2))
credit = fields.Float(digits=(16, 2)) credit = fields.Float(digits=(16, 2))
period_balance = fields.Float(digits=(16, 2))
currency_id = fields.Many2one(comodel_name='res.currency') currency_id = fields.Many2one(comodel_name='res.currency')
final_balance = fields.Float(digits=(16, 2)) final_balance = fields.Float(digits=(16, 2))
final_balance_foreign_currency = fields.Float(digits=(16, 2)) final_balance_foreign_currency = fields.Float(digits=(16, 2))
@ -85,6 +115,21 @@ class TrialBalanceReportAccount(models.TransientModel):
inverse_name='report_account_id' inverse_name='report_account_id'
) )
@api.multi
def _compute_hide_line(self):
for rec in self:
report = rec.report_id
rec.hide_line = False
if report.hide_account_at_0 and (
not rec.initial_balance and
not rec.final_balance and
not rec.debit and
not rec.credit):
rec.hide_line = True
elif report.limit_hierarchy_level and \
rec.level > report.show_hierarchy_level:
rec.hide_line = True
class TrialBalanceReportPartner(models.TransientModel): class TrialBalanceReportPartner(models.TransientModel):
@ -110,6 +155,7 @@ class TrialBalanceReportPartner(models.TransientModel):
initial_balance_foreign_currency = fields.Float(digits=(16, 2)) initial_balance_foreign_currency = fields.Float(digits=(16, 2))
debit = fields.Float(digits=(16, 2)) debit = fields.Float(digits=(16, 2))
credit = fields.Float(digits=(16, 2)) credit = fields.Float(digits=(16, 2))
period_balance = fields.Float(digits=(16, 2))
currency_id = fields.Many2one(comodel_name='res.currency') currency_id = fields.Many2one(comodel_name='res.currency')
final_balance = fields.Float(digits=(16, 2)) final_balance = fields.Float(digits=(16, 2))
final_balance_foreign_currency = fields.Float(digits=(16, 2)) final_balance_foreign_currency = fields.Float(digits=(16, 2))
@ -169,7 +215,7 @@ class TrialBalanceReportCompute(models.TransientModel):
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'only_posted_moves': self.only_posted_moves, 'only_posted_moves': self.only_posted_moves,
'hide_account_balance_at_0': self.hide_account_balance_at_0,
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, account_ids.ids)], 'filter_account_ids': [(6, 0, account_ids.ids)],
@ -201,8 +247,21 @@ class TrialBalanceReportCompute(models.TransientModel):
self._inject_account_values(account_ids) self._inject_account_values(account_ids)
if self.show_partner_details: if self.show_partner_details:
self._inject_partner_values() self._inject_partner_values()
# Refresh cache because all data are computed with SQL requests
self.invalidate_cache()
if not self.filter_account_ids:
if self.hierarchy_on != 'none':
self._inject_account_group_values()
if self.hierarchy_on == 'computed':
self._update_account_group_computed_values()
else:
self._update_account_group_child_values()
self._update_account_sequence()
self._add_account_group_account_values()
self.refresh()
if not self.filter_account_ids and self.hierarchy_on != 'none':
self._compute_group_accounts()
else:
for line in self.account_ids:
line.write({'level': 0})
def _inject_account_values(self, account_ids): def _inject_account_values(self, account_ids):
"""Inject report values for report_trial_balance_qweb_account""" """Inject report values for report_trial_balance_qweb_account"""
@ -214,11 +273,13 @@ INSERT INTO
create_uid, create_uid,
create_date, create_date,
account_id, account_id,
parent_id,
code, code,
name, name,
initial_balance, initial_balance,
debit, debit,
credit, credit,
period_balance,
final_balance, final_balance,
currency_id, currency_id,
initial_balance_foreign_currency, initial_balance_foreign_currency,
@ -229,11 +290,13 @@ SELECT
%s AS create_uid, %s AS create_uid,
NOW() AS create_date, NOW() AS create_date,
acc.id, acc.id,
acc.group_id,
acc.code, acc.code,
acc.name, acc.name,
coalesce(rag.initial_balance, 0) AS initial_balance, coalesce(rag.initial_balance, 0) AS initial_balance,
coalesce(rag.final_debit - rag.initial_debit, 0) AS debit, coalesce(rag.final_debit - rag.initial_debit, 0) AS debit,
coalesce(rag.final_credit - rag.initial_credit, 0) AS credit, coalesce(rag.final_credit - rag.initial_credit, 0) AS credit,
coalesce(rag.final_balance - rag.initial_balance, 0) AS period_balance,
coalesce(rag.final_balance, 0) AS final_balance, coalesce(rag.final_balance, 0) AS final_balance,
rag.currency_id AS currency_id, rag.currency_id AS currency_id,
coalesce(rag.initial_balance_foreign_currency, 0) coalesce(rag.initial_balance_foreign_currency, 0)
@ -247,9 +310,6 @@ FROM
WHERE WHERE
acc.id in %s acc.id in %s
""" """
if self.hide_account_balance_at_0:
query_inject_account += """ AND
final_balance IS NOT NULL AND final_balance != 0"""
query_inject_account_params = ( query_inject_account_params = (
self.id, self.id,
self.env.uid, self.env.uid,
@ -273,6 +333,7 @@ INSERT INTO
initial_balance_foreign_currency, initial_balance_foreign_currency,
debit, debit,
credit, credit,
period_balance,
final_balance, final_balance,
final_balance_foreign_currency final_balance_foreign_currency
) )
@ -286,6 +347,7 @@ SELECT
rpg.initial_balance_foreign_currency AS initial_balance_foreign_currency, rpg.initial_balance_foreign_currency AS initial_balance_foreign_currency,
rpg.final_debit - rpg.initial_debit AS debit, rpg.final_debit - rpg.initial_debit AS debit,
rpg.final_credit - rpg.initial_credit AS credit, rpg.final_credit - rpg.initial_credit AS credit,
rpg.final_balance - rpg.initial_balance AS period_balance,
rpg.final_balance AS final_balance, rpg.final_balance AS final_balance,
rpg.final_balance_foreign_currency AS final_balance_foreign_currency rpg.final_balance_foreign_currency AS final_balance_foreign_currency
FROM FROM
@ -304,3 +366,207 @@ AND ra.report_id = %s
self.id, self.id,
) )
self.env.cr.execute(query_inject_partner, query_inject_partner_params) self.env.cr.execute(query_inject_partner, query_inject_partner_params)
def _inject_account_group_values(self):
"""Inject report values for report_trial_balance_qweb_account"""
query_inject_account_group = """
INSERT INTO
report_trial_balance_qweb_account
(
report_id,
create_uid,
create_date,
account_group_id,
parent_id,
code,
name,
sequence,
level
)
SELECT
%s AS report_id,
%s AS create_uid,
NOW() AS create_date,
accgroup.id,
accgroup.parent_id,
coalesce(accgroup.code_prefix, accgroup.name),
accgroup.name,
accgroup.parent_left * 100000,
accgroup.level
FROM
account_group accgroup"""
query_inject_account_params = (
self.id,
self.env.uid,
)
self.env.cr.execute(query_inject_account_group,
query_inject_account_params)
def _update_account_group_child_values(self):
"""Compute values for report_trial_balance_qweb_account group
in child."""
query_update_account_group = """
WITH computed AS (WITH RECURSIVE cte AS (
SELECT account_group_id, code, account_group_id AS parent_id,
initial_balance, initial_balance_foreign_currency, debit, credit,
period_balance, final_balance, final_balance_foreign_currency
FROM report_trial_balance_qweb_account
WHERE report_id = %s
GROUP BY report_trial_balance_qweb_account.id
UNION ALL
SELECT c.account_group_id, c.code, p.account_group_id,
p.initial_balance, p.initial_balance_foreign_currency, p.debit, p.credit,
p.period_balance, p.final_balance, p.final_balance_foreign_currency
FROM cte c
JOIN report_trial_balance_qweb_account p USING (parent_id)
WHERE p.report_id = %s
)
SELECT account_group_id, code,
sum(initial_balance) AS initial_balance,
sum(initial_balance_foreign_currency) AS initial_balance_foreign_currency,
sum(debit) AS debit,
sum(credit) AS credit,
sum(debit) - sum(credit) AS period_balance,
sum(final_balance) AS final_balance,
sum(final_balance_foreign_currency) AS final_balance_foreign_currency
FROM cte
GROUP BY cte.account_group_id, cte.code
ORDER BY account_group_id
)
UPDATE report_trial_balance_qweb_account
SET initial_balance = computed.initial_balance,
initial_balance_foreign_currency =
computed.initial_balance_foreign_currency,
debit = computed.debit,
credit = computed.credit,
period_balance = computed.period_balance,
final_balance = computed.final_balance,
final_balance_foreign_currency =
computed.final_balance_foreign_currency
FROM computed
WHERE report_trial_balance_qweb_account.account_group_id =
computed.account_group_id
AND report_trial_balance_qweb_account.report_id = %s
"""
query_update_account_params = (self.id, self.id, self.id,)
self.env.cr.execute(query_update_account_group,
query_update_account_params)
def _add_account_group_account_values(self):
"""Compute values for report_trial_balance_qweb_account group in
child."""
query_update_account_group = """
DROP AGGREGATE IF EXISTS array_concat_agg(anyarray);
CREATE AGGREGATE array_concat_agg(anyarray) (
SFUNC = array_cat,
STYPE = anyarray
);
WITH aggr AS(WITH computed AS (WITH RECURSIVE cte AS (
SELECT account_group_id, account_group_id AS parent_id,
ARRAY[account_id]::int[] as child_account_ids
FROM report_trial_balance_qweb_account
WHERE report_id = %s
GROUP BY report_trial_balance_qweb_account.id
UNION ALL
SELECT c.account_group_id, p.account_group_id, ARRAY[p.account_id]::int[]
FROM cte c
JOIN report_trial_balance_qweb_account p USING (parent_id)
WHERE p.report_id = %s
)
SELECT account_group_id,
array_concat_agg(DISTINCT child_account_ids)::int[] as child_account_ids
FROM cte
GROUP BY cte.account_group_id, cte.child_account_ids
ORDER BY account_group_id
)
SELECT account_group_id,
array_concat_agg(DISTINCT child_account_ids)::int[]
AS child_account_ids from computed
GROUP BY account_group_id)
UPDATE report_trial_balance_qweb_account
SET child_account_ids = aggr.child_account_ids
FROM aggr
WHERE report_trial_balance_qweb_account.account_group_id =
aggr.account_group_id
AND report_trial_balance_qweb_account.report_id = %s
"""
query_update_account_params = (self.id, self.id, self.id,)
self.env.cr.execute(query_update_account_group,
query_update_account_params)
def _update_account_group_computed_values(self):
"""Compute values for report_trial_balance_qweb_account group
in compute."""
query_update_account_group = """
WITH RECURSIVE accgroup AS
(SELECT
accgroup.id,
sum(coalesce(ra.initial_balance, 0)) as initial_balance,
sum(coalesce(ra.initial_balance_foreign_currency, 0))
as initial_balance_foreign_currency,
sum(coalesce(ra.debit, 0)) as debit,
sum(coalesce(ra.credit, 0)) as credit,
sum(coalesce(ra.debit, 0)) - sum(coalesce(ra.credit, 0)) as period_balance,
sum(coalesce(ra.final_balance, 0)) as final_balance,
sum(coalesce(ra.final_balance_foreign_currency, 0))
as final_balance_foreign_currency
FROM
account_group accgroup
LEFT OUTER JOIN account_account AS acc
ON strpos(acc.code, accgroup.code_prefix) = 1
LEFT OUTER JOIN report_trial_balance_qweb_account AS ra
ON ra.account_id = acc.id
WHERE ra.report_id = %s
GROUP BY accgroup.id
)
UPDATE report_trial_balance_qweb_account
SET initial_balance = accgroup.initial_balance,
initial_balance_foreign_currency =
accgroup.initial_balance_foreign_currency,
debit = accgroup.debit,
credit = accgroup.credit,
period_balance = accgroup.period_balance,
final_balance = accgroup.final_balance,
final_balance_foreign_currency =
accgroup.final_balance_foreign_currency
FROM accgroup
WHERE report_trial_balance_qweb_account.account_group_id = accgroup.id
"""
query_update_account_params = (self.id,)
self.env.cr.execute(query_update_account_group,
query_update_account_params)
def _update_account_sequence(self):
"""Compute sequence, level for report_trial_balance_qweb_
account account."""
query_update_account_group = """
UPDATE report_trial_balance_qweb_account
SET sequence = newline.sequence + 1,
level = newline.level + 1
FROM report_trial_balance_qweb_account as newline
WHERE newline.account_group_id = report_trial_balance_qweb_account.parent_id
AND report_trial_balance_qweb_account.report_id = newline.report_id
AND report_trial_balance_qweb_account.account_id is not null
AND report_trial_balance_qweb_account.report_id = %s"""
query_update_account_params = (self.id,)
self.env.cr.execute(query_update_account_group,
query_update_account_params)
def _compute_group_accounts(self):
groups = self.account_ids.filtered(
lambda a: a.account_group_id is not False)
for group in groups:
if self.hierarchy_on == 'compute':
group.compute_account_ids = \
group.account_group_id.compute_account_ids
else:
if group.child_account_ids:
chacc = group.child_account_ids.replace(
'}', '').replace('{', '').split(',')
if 'NULL' in chacc:
chacc.remove('NULL')
if chacc:
group.compute_account_ids = [
(6, 0, [int(g) for g in chacc])]

19
account_financial_report_qweb/report/trial_balance_xlsx.py

@ -35,7 +35,11 @@ class TrialBalanceXslx(abstract_report_xlsx.AbstractReportXslx):
'field': 'credit', 'field': 'credit',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
5: {'header': _('Ending balance'),
5: {'header': _('Period balance'),
'field': 'period_balance',
'type': 'amount',
'width': 14},
6: {'header': _('Ending balance'),
'field': 'final_balance', 'field': 'final_balance',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
@ -72,7 +76,11 @@ class TrialBalanceXslx(abstract_report_xlsx.AbstractReportXslx):
'field': 'credit', 'field': 'credit',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
4: {'header': _('Ending balance'),
4: {'header': _('Period balance'),
'field': 'period_balance',
'type': 'amount',
'width': 14},
5: {'header': _('Ending balance'),
'field': 'final_balance', 'field': 'final_balance',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
@ -103,9 +111,12 @@ class TrialBalanceXslx(abstract_report_xlsx.AbstractReportXslx):
_('All posted entries') if report.only_posted_moves _('All posted entries') if report.only_posted_moves
else _('All entries')], else _('All entries')],
[_('Account balance at 0 filter'), [_('Account balance at 0 filter'),
_('Hide') if report.hide_account_balance_at_0 else _('Show')],
_('Hide') if report.hide_account_at_0 else _('Show')],
[_('Show foreign currency'), [_('Show foreign currency'),
_('Yes') if report.foreign_currency else _('No')], _('Yes') if report.foreign_currency else _('No')],
[_('Limit hierarchy levels'),
_('Level %s' % report.show_hierarchy_level) if
report.limit_hierarchy_level else _('No limit')],
] ]
def _get_col_count_filter_name(self): def _get_col_count_filter_name(self):
@ -121,7 +132,7 @@ class TrialBalanceXslx(abstract_report_xlsx.AbstractReportXslx):
self.write_array_header() self.write_array_header()
# For each account # For each account
for account in report.account_ids:
for account in report.account_ids.filtered(lambda a: not a.hide_line):
if not report.show_partner_details: if not report.show_partner_details:
# Display account lines # Display account lines
self.write_line(account, 'account') self.write_line(account, 'account')

40
account_financial_report_qweb/tests/test_general_ledger.py

@ -42,14 +42,14 @@ class TestGeneralLedger(a_t_f_c.AbstractTestForeignCurrency):
def _getAdditionalFiltersToBeTested(self): def _getAdditionalFiltersToBeTested(self):
additional_filters = [ additional_filters = [
{'only_posted_moves': True}, {'only_posted_moves': True},
{'hide_account_balance_at_0': True},
{'hide_account_at_0': True},
{'centralize': True}, {'centralize': True},
{'only_posted_moves': True, 'hide_account_balance_at_0': True},
{'only_posted_moves': True, 'hide_account_at_0': True},
{'only_posted_moves': True, 'centralize': True}, {'only_posted_moves': True, 'centralize': True},
{'hide_account_balance_at_0': True, 'centralize': True},
{'hide_account_at_0': True, 'centralize': True},
{ {
'only_posted_moves': True, 'only_posted_moves': True,
'hide_account_balance_at_0': True,
'hide_account_at_0': True,
'centralize': True 'centralize': True
}, },
] ]
@ -155,7 +155,7 @@ class TestGeneralLedgerReport(common.TransactionCase):
'date_from': self.fy_date_start, 'date_from': self.fy_date_start,
'date_to': self.fy_date_end, 'date_to': self.fy_date_end,
'only_posted_moves': True, 'only_posted_moves': True,
'hide_account_balance_at_0': False,
'hide_account_at_0': False,
'company_id': company.id, 'company_id': company.id,
'fy_start_date': self.fy_date_start, 'fy_start_date': self.fy_date_start,
}) })
@ -377,10 +377,10 @@ class TestGeneralLedgerReport(common.TransactionCase):
# Check the initial and final balance # Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0) self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 1000)
self.assertEqual(lines['unaffected'].initial_balance, -1000) self.assertEqual(lines['unaffected'].initial_balance, -1000)
self.assertEqual(lines['unaffected'].final_debit, -0)
self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_debit, 0)
self.assertEqual(lines['unaffected'].final_credit, 1000)
self.assertEqual(lines['unaffected'].final_balance, -1000) self.assertEqual(lines['unaffected'].final_balance, -1000)
# Add reversale move of the initial move the first day of fiscal year # Add reversale move of the initial move the first day of fiscal year
@ -402,11 +402,11 @@ class TestGeneralLedgerReport(common.TransactionCase):
# Check the initial and final balance # Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0) self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 1000)
self.assertEqual(lines['unaffected'].initial_balance, -1000) self.assertEqual(lines['unaffected'].initial_balance, -1000)
self.assertEqual(lines['unaffected'].final_debit, 0)
self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_balance, -1000)
self.assertEqual(lines['unaffected'].final_debit, 1000)
self.assertEqual(lines['unaffected'].final_credit, 1000)
self.assertEqual(lines['unaffected'].final_balance, 0)
# Add another move at the end day of fiscal year # Add another move at the end day of fiscal year
# to check that it correctly used on report # to check that it correctly used on report
@ -426,11 +426,11 @@ class TestGeneralLedgerReport(common.TransactionCase):
# Check the initial and final balance # Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0) self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 1000)
self.assertEqual(lines['unaffected'].initial_balance, -1000) self.assertEqual(lines['unaffected'].initial_balance, -1000)
self.assertEqual(lines['unaffected'].final_debit, 0)
self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_balance, -4000)
self.assertEqual(lines['unaffected'].final_debit, 1000)
self.assertEqual(lines['unaffected'].final_credit, 4000)
self.assertEqual(lines['unaffected'].final_balance, -3000)
def test_04_unaffected_account_balance_2_years(self): def test_04_unaffected_account_balance_2_years(self):
# Generate the general ledger line # Generate the general ledger line
@ -460,10 +460,10 @@ class TestGeneralLedgerReport(common.TransactionCase):
self.assertEqual(len(lines['unaffected']), 1) self.assertEqual(len(lines['unaffected']), 1)
# Check the initial and final balance # Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_debit, 1000)
self.assertEqual(lines['unaffected'].initial_credit, 0) self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_balance, 1000) self.assertEqual(lines['unaffected'].initial_balance, 1000)
self.assertEqual(lines['unaffected'].final_debit, 0)
self.assertEqual(lines['unaffected'].final_debit, 1000)
self.assertEqual(lines['unaffected'].final_credit, 0) self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_balance, 1000) self.assertEqual(lines['unaffected'].final_balance, 1000)
@ -493,9 +493,9 @@ class TestGeneralLedgerReport(common.TransactionCase):
self.assertEqual(len(lines['unaffected']), 1) self.assertEqual(len(lines['unaffected']), 1)
# Check the initial and final balance # Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_debit, 500)
self.assertEqual(lines['unaffected'].initial_credit, 0) self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_balance, 500) self.assertEqual(lines['unaffected'].initial_balance, 500)
self.assertEqual(lines['unaffected'].final_debit, 0)
self.assertEqual(lines['unaffected'].final_debit, 500)
self.assertEqual(lines['unaffected'].final_credit, 0) self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_balance, 500) self.assertEqual(lines['unaffected'].final_balance, 500)

4
account_financial_report_qweb/tests/test_open_items.py

@ -37,6 +37,6 @@ class TestOpenItems(a_t_f_c.AbstractTestForeignCurrency):
def _getAdditionalFiltersToBeTested(self): def _getAdditionalFiltersToBeTested(self):
return [ return [
{'only_posted_moves': True}, {'only_posted_moves': True},
{'hide_account_balance_at_0': True},
{'only_posted_moves': True, 'hide_account_balance_at_0': True},
{'hide_account_at_0': True},
{'only_posted_moves': True, 'hide_account_at_0': True},
] ]

8
account_financial_report_qweb/tests/test_trial_balance.py

@ -41,14 +41,14 @@ class TestTrialBalance(a_t_f_c.AbstractTestForeignCurrency):
def _getAdditionalFiltersToBeTested(self): def _getAdditionalFiltersToBeTested(self):
return [ return [
{'only_posted_moves': True}, {'only_posted_moves': True},
{'hide_account_balance_at_0': True},
{'hide_account_at_0': True},
{'show_partner_details': True}, {'show_partner_details': True},
{'only_posted_moves': True, 'hide_account_balance_at_0': True},
{'only_posted_moves': True, 'hide_account_at_0': True},
{'only_posted_moves': True, 'show_partner_details': True}, {'only_posted_moves': True, 'show_partner_details': True},
{'hide_account_balance_at_0': True, 'show_partner_details': True},
{'hide_account_at_0': True, 'show_partner_details': True},
{ {
'only_posted_moves': True, 'only_posted_moves': True,
'hide_account_balance_at_0': True,
'hide_account_at_0': True,
'show_partner_details': True 'show_partner_details': True
}, },
] ]

3
account_financial_report_qweb/wizard/aged_partner_balance_wizard.py

@ -4,7 +4,6 @@
# Copyright 2016 Camptocamp SA, Onestein B.V. # Copyright 2016 Camptocamp SA, Onestein B.V.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import datetime
from odoo import api, fields, models from odoo import api, fields, models
from odoo.tools.safe_eval import safe_eval from odoo.tools.safe_eval import safe_eval
@ -21,7 +20,7 @@ class AgedPartnerBalance(models.TransientModel):
string='Company' string='Company'
) )
date_at = fields.Date(required=True, date_at = fields.Date(required=True,
default=fields.Date.to_string(datetime.today()))
default=fields.Date.context_today)
target_move = fields.Selection([('posted', 'All Posted Entries'), target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')], ('all', 'All Entries')],
string='Target Moves', string='Target Moves',

4
account_financial_report_qweb/wizard/general_ledger_wizard.py

@ -38,7 +38,7 @@ class GeneralLedgerReportWizard(models.TransientModel):
) )
centralize = fields.Boolean(string='Activate centralization', centralize = fields.Boolean(string='Activate centralization',
default=True) default=True)
hide_account_balance_at_0 = fields.Boolean(
hide_account_at_0 = fields.Boolean(
string='Hide account ending balance at 0', string='Hide account ending balance at 0',
help='Use this filter to hide an account or a partner ' help='Use this filter to hide an account or a partner '
'with an ending balance at 0. ' 'with an ending balance at 0. '
@ -181,7 +181,7 @@ class GeneralLedgerReportWizard(models.TransientModel):
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted', 'only_posted_moves': self.target_move == 'posted',
'hide_account_balance_at_0': self.hide_account_balance_at_0,
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'show_analytic_tags': self.show_analytic_tags, 'show_analytic_tags': self.show_analytic_tags,
'company_id': self.company_id.id, 'company_id': self.company_id.id,

2
account_financial_report_qweb/wizard/general_ledger_wizard_view.xml

@ -22,7 +22,7 @@
<group name="other_filters"> <group name="other_filters">
<field name="target_move" widget="radio"/> <field name="target_move" widget="radio"/>
<field name="centralize"/> <field name="centralize"/>
<field name="hide_account_balance_at_0"/>
<field name="hide_account_at_0"/>
<field name="foreign_currency"/> <field name="foreign_currency"/>
<field name="show_analytic_tags"/> <field name="show_analytic_tags"/>
</group> </group>

9
account_financial_report_qweb/wizard/journal_report_wizard.py

@ -36,7 +36,7 @@ class JournalReportWizard(models.TransientModel):
comodel_name='account.journal', comodel_name='account.journal',
string="Journals", string="Journals",
domain="[('company_id', '=', company_id)]", domain="[('company_id', '=', company_id)]",
required=True,
required=False,
) )
move_target = fields.Selection( move_target = fields.Selection(
selection='_get_move_targets', selection='_get_move_targets',
@ -119,13 +119,18 @@ class JournalReportWizard(models.TransientModel):
@api.multi @api.multi
def _prepare_report_journal(self): def _prepare_report_journal(self):
self.ensure_one() self.ensure_one()
journals = self.journal_ids
if not journals:
# Not selecting a journal means that we'll display all journals
journals = self.env['account.journal'].search(
[('company_id', '=', self.company_id.id)])
return { return {
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'move_target': self.move_target, 'move_target': self.move_target,
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'journal_ids': [(6, 0, self.journal_ids.ids)],
'journal_ids': [(6, 0, journals.ids)],
'sort_option': self.sort_option, 'sort_option': self.sort_option,
'group_option': self.group_option, 'group_option': self.group_option,
'with_account_name': self.with_account_name, 'with_account_name': self.with_account_name,

7
account_financial_report_qweb/wizard/open_items_wizard.py

@ -4,7 +4,6 @@
# Copyright 2016 Camptocamp SA # Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import datetime
from odoo import models, fields, api from odoo import models, fields, api
from odoo.tools.safe_eval import safe_eval from odoo.tools.safe_eval import safe_eval
@ -21,7 +20,7 @@ class OpenItemsReportWizard(models.TransientModel):
string='Company' string='Company'
) )
date_at = fields.Date(required=True, date_at = fields.Date(required=True,
default=fields.Date.to_string(datetime.today()))
default=fields.Date.context_today)
target_move = fields.Selection([('posted', 'All Posted Entries'), target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')], ('all', 'All Entries')],
string='Target Moves', string='Target Moves',
@ -32,7 +31,7 @@ class OpenItemsReportWizard(models.TransientModel):
string='Filter accounts', string='Filter accounts',
domain=[('reconcile', '=', True)], domain=[('reconcile', '=', True)],
) )
hide_account_balance_at_0 = fields.Boolean(
hide_account_at_0 = fields.Boolean(
string='Hide account ending balance at 0', string='Hide account ending balance at 0',
help='Use this filter to hide an account or a partner ' help='Use this filter to hide an account or a partner '
'with an ending balance at 0. ' 'with an ending balance at 0. '
@ -122,7 +121,7 @@ class OpenItemsReportWizard(models.TransientModel):
return { return {
'date_at': self.date_at, 'date_at': self.date_at,
'only_posted_moves': self.target_move == 'posted', 'only_posted_moves': self.target_move == 'posted',
'hide_account_balance_at_0': self.hide_account_balance_at_0,
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)], 'filter_account_ids': [(6, 0, self.account_ids.ids)],

2
account_financial_report_qweb/wizard/open_items_wizard_view.xml

@ -16,7 +16,7 @@
</group> </group>
<group name="other_filters"> <group name="other_filters">
<field name="target_move" widget="radio"/> <field name="target_move" widget="radio"/>
<field name="hide_account_balance_at_0"/>
<field name="hide_account_at_0"/>
<field name="foreign_currency"/> <field name="foreign_currency"/>
</group> </group>
</group> </group>

48
account_financial_report_qweb/wizard/trial_balance_wizard.py

@ -2,10 +2,12 @@
# Author: Julien Coux # Author: Julien Coux
# Copyright 2016 Camptocamp SA # Copyright 2016 Camptocamp SA
# Copyright 2017 Akretion - Alexis de Lattre # Copyright 2017 Akretion - Alexis de Lattre
# Copyright 2018 Eficent Business and IT Consuting Services, S.L.
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
from odoo import api, fields, models, _
from odoo.tools.safe_eval import safe_eval from odoo.tools.safe_eval import safe_eval
from odoo.exceptions import UserError
class TrialBalanceReportWizard(models.TransientModel): class TrialBalanceReportWizard(models.TransientModel):
@ -31,16 +33,31 @@ class TrialBalanceReportWizard(models.TransientModel):
string='Target Moves', string='Target Moves',
required=True, required=True,
default='all') default='all')
hierarchy_on = fields.Selection(
[('computed', 'Computed Accounts'),
('relation', 'Child Accounts'),
('none', 'No hierarchy')],
string='Hierarchy On',
required=True,
default='computed',
help="""Computed Accounts: Use when the account group have codes
that represent prefixes of the actual accounts.\n
Child Accounts: Use when your account groups are hierarchical.\n
No hierarchy: Use to display just the accounts, without any grouping.
""",
)
limit_hierarchy_level = fields.Boolean('Limit hierarchy levels')
show_hierarchy_level = fields.Integer('Hierarchy Levels to display',
default=1)
account_ids = fields.Many2many( account_ids = fields.Many2many(
comodel_name='account.account', comodel_name='account.account',
string='Filter accounts', string='Filter accounts',
) )
hide_account_balance_at_0 = fields.Boolean(
string='Hide account ending balance at 0',
help='Use this filter to hide an account or a partner '
'with an ending balance at 0. '
'If partners are filtered, '
'debits and credits totals will not match the trial balance.'
hide_account_at_0 = fields.Boolean(
string='Hide accounts at 0', default=True,
help='When this option is enabled, the trial balance will '
'not display accounts that have initial balance = '
'debit = credit = end balance = 0',
) )
receivable_accounts_only = fields.Boolean() receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean() payable_accounts_only = fields.Boolean()
@ -66,6 +83,14 @@ class TrialBalanceReportWizard(models.TransientModel):
'will display initial and final balance in that currency.' 'will display initial and final balance in that currency.'
) )
@api.multi
@api.constrains('hierarchy_on', 'show_hierarchy_level')
def _check_show_hierarchy_level(self):
for rec in self:
if rec.hierarchy_on != 'none' and rec.show_hierarchy_level <= 0:
raise UserError(_('The hierarchy level to filter on must be '
'greater than 0.'))
@api.depends('date_from') @api.depends('date_from')
def _compute_fy_start_date(self): def _compute_fy_start_date(self):
for wiz in self.filtered('date_from'): for wiz in self.filtered('date_from'):
@ -131,10 +156,10 @@ class TrialBalanceReportWizard(models.TransientModel):
"""Handle partners change.""" """Handle partners change."""
if self.show_partner_details: if self.show_partner_details:
self.receivable_accounts_only = self.payable_accounts_only = True self.receivable_accounts_only = self.payable_accounts_only = True
self.hide_account_balance_at_0 = True
self.hide_account_at_0 = True
else: else:
self.receivable_accounts_only = self.payable_accounts_only = False self.receivable_accounts_only = self.payable_accounts_only = False
self.hide_account_balance_at_0 = False
self.hide_account_at_0 = False
@api.multi @api.multi
def button_export_html(self): def button_export_html(self):
@ -171,13 +196,16 @@ class TrialBalanceReportWizard(models.TransientModel):
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted', 'only_posted_moves': self.target_move == 'posted',
'hide_account_balance_at_0': self.hide_account_balance_at_0,
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)], 'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_partner_ids': [(6, 0, self.partner_ids.ids)], 'filter_partner_ids': [(6, 0, self.partner_ids.ids)],
'filter_journal_ids': [(6, 0, self.journal_ids.ids)], 'filter_journal_ids': [(6, 0, self.journal_ids.ids)],
'fy_start_date': self.fy_start_date, 'fy_start_date': self.fy_start_date,
'hierarchy_on': self.hierarchy_on,
'limit_hierarchy_level': self.limit_hierarchy_level,
'show_hierarchy_level': self.show_hierarchy_level,
'show_partner_details': self.show_partner_details, 'show_partner_details': self.show_partner_details,
} }

5
account_financial_report_qweb/wizard/trial_balance_wizard_view.xml

@ -21,8 +21,11 @@
</group> </group>
<group name="other_filters"> <group name="other_filters">
<field name="target_move" widget="radio"/> <field name="target_move" widget="radio"/>
<field name="hide_account_balance_at_0"/>
<field name="hide_account_at_0"/>
<field name="show_partner_details"/> <field name="show_partner_details"/>
<field name="hierarchy_on" widget="radio" attrs="{'invisible':[('show_partner_details','=',True)]}"/>
<field name="limit_hierarchy_level" attrs="{'invisible':['|', ('hierarchy_on','=','none'),('show_partner_details','=',True)]}"/>
<field name="show_hierarchy_level" attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"/>
<field name="foreign_currency"/> <field name="foreign_currency"/>
</group> </group>
</group> </group>

Loading…
Cancel
Save