Browse Source

[12.0] account_financial_report: refactor

pull/663/head
Joan Sisquella 4 years ago
committed by Ernesto Tejeda
parent
commit
e41e718bfc
  1. 10
      account_financial_report/__manifest__.py
  2. 22
      account_financial_report/models/account_group.py
  3. 5
      account_financial_report/readme/CONTRIBUTORS.rst
  4. 1
      account_financial_report/report/__init__.py
  5. 23
      account_financial_report/report/abstract_report.py
  6. 193
      account_financial_report/report/abstract_report_xlsx.py
  7. 971
      account_financial_report/report/aged_partner_balance.py
  8. 181
      account_financial_report/report/aged_partner_balance_xlsx.py
  9. 2334
      account_financial_report/report/general_ledger.py
  10. 176
      account_financial_report/report/general_ledger_xlsx.py
  11. 1167
      account_financial_report/report/journal_ledger.py
  12. 112
      account_financial_report/report/journal_ledger_xlsx.py
  13. 1208
      account_financial_report/report/open_items.py
  14. 121
      account_financial_report/report/open_items_xlsx.py
  15. 438
      account_financial_report/report/templates/aged_partner_balance.xml
  16. 347
      account_financial_report/report/templates/general_ledger.xml
  17. 110
      account_financial_report/report/templates/journal_ledger.xml
  18. 106
      account_financial_report/report/templates/open_items.xml
  19. 1033
      account_financial_report/report/templates/trial_balance.xml
  20. 172
      account_financial_report/report/templates/vat_report.xml
  21. 1190
      account_financial_report/report/trial_balance.py
  22. 110
      account_financial_report/report/trial_balance_xlsx.py
  23. 525
      account_financial_report/report/vat_report.py
  24. 38
      account_financial_report/report/vat_report_xlsx.py
  25. 152
      account_financial_report/reports.xml
  26. 4
      account_financial_report/tests/__init__.py
  27. 399
      account_financial_report/tests/abstract_test.py
  28. 78
      account_financial_report/tests/abstract_test_foreign_currency.py
  29. 75
      account_financial_report/tests/abstract_test_tax_report.py
  30. 41
      account_financial_report/tests/test_aged_partner_balance.py
  31. 561
      account_financial_report/tests/test_general_ledger.py
  32. 206
      account_financial_report/tests/test_journal_ledger.py
  33. 37
      account_financial_report/tests/test_open_items.py
  34. 649
      account_financial_report/tests/test_trial_balance.py
  35. 243
      account_financial_report/tests/test_vat_report.py
  36. 20
      account_financial_report/view/report_template.xml
  37. 49
      account_financial_report/wizard/aged_partner_balance_wizard.py
  38. 4
      account_financial_report/wizard/aged_partner_balance_wizard_view.xml
  39. 71
      account_financial_report/wizard/general_ledger_wizard.py
  40. 79
      account_financial_report/wizard/journal_ledger_wizard.py
  41. 53
      account_financial_report/wizard/open_items_wizard.py
  42. 1
      account_financial_report/wizard/open_items_wizard_view.xml
  43. 67
      account_financial_report/wizard/trial_balance_wizard.py
  44. 2
      account_financial_report/wizard/trial_balance_wizard_view.xml
  45. 36
      account_financial_report/wizard/vat_report_wizard.py

10
account_financial_report/__manifest__.py

@ -1,16 +1,17 @@
# Author: Damien Crier
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Account Financial Reports',
'version': '12.0.1.2.2',
'version': '12.0.2.0.0',
'category': 'Reporting',
'summary': 'OCA Financial Reports',
'author': 'Camptocamp SA,'
'initOS GmbH,'
'redCOR AG,'
'Eficent,'
'ForgeFlow,'
'Odoo Community Association (OCA)',
"website": "https://odoo-community.org/",
'depends': [
@ -43,6 +44,11 @@
'view/report_aged_partner_balance.xml',
'view/report_vat_report.xml',
],
"external_dependencies": {
"python": ['natsort',
'pandas',
],
},
'installable': True,
'application': True,
'auto_install': False,

22
account_financial_report/models/account_group.py

@ -23,6 +23,28 @@ class AccountGroup(models.Model):
'account.account',
compute='_compute_group_accounts',
string="Compute accounts", store=True)
complete_name = fields.Char("Full Name",
compute='_compute_complete_name')
complete_code = fields.Char("Full Code",
compute='_compute_complete_code')
@api.depends('name', 'parent_id.complete_name')
def _compute_complete_name(self):
""" Forms complete name of location from parent location to child location. """
if self.parent_id.complete_name:
self.complete_name = '%s/%s' % (self.parent_id.complete_name,
self.name)
else:
self.complete_name = self.name
@api.depends('code_prefix', 'parent_id.complete_code')
def _compute_complete_code(self):
""" Forms complete code of location from parent location to child location. """
if self.parent_id.complete_code:
self.complete_code = '%s/%s' % (self.parent_id.complete_code,
self.code_prefix)
else:
self.complete_code = self.code_prefix
@api.multi
@api.depends('parent_id', 'parent_id.level')

5
account_financial_report/readme/CONTRIBUTORS.rst

@ -1,4 +1,4 @@
* Jordi Ballester <jordi.ballester@eficient.com>
* Jordi Ballester <jordi.ballester@forgeflow.com>
* Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Simone Orsi <simone.orsi@abstract.com>
* Leonardo Pistone <leonardo.pistone@camptocamp.com>
@ -14,7 +14,8 @@
* Akim Juillerat <akim.juillerat@camptocamp.com>
* Alexis de Lattre <alexis@via.ecp.fr>
* Mihai Fekete <feketemihai@gmail.com>
* Miquel Raïch <miquel.raich@eficent.com>
* Miquel Raïch <miquel.raich@forgeflow.com>
* Joan Sisquella <joan.sisquella@forgeflow.com>
* `Tecnativa <https://www.tecnativa.com>`__:
* Pedro M. Baeza

1
account_financial_report/report/__init__.py

@ -3,7 +3,6 @@
# © 2016 Julien Coux (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-
from . import abstract_report
from . import abstract_report_xlsx
from . import aged_partner_balance
from . import aged_partner_balance_xlsx

23
account_financial_report/report/abstract_report.py

@ -1,23 +0,0 @@
# Copyright 2018 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models
from psycopg2.extensions import AsIs
class AbstractReport(models.AbstractModel):
_name = 'account_financial_report_abstract'
_description = 'Abstract Report'
def _transient_clean_rows_older_than(self, seconds):
assert self._transient, \
"Model %s is not transient, it cannot be vacuumed!" % self._name
# Never delete rows used in last 5 minutes
seconds = max(seconds, 300)
query = (
"DELETE FROM %s"
" WHERE COALESCE("
"write_date, create_date, (now() at time zone 'UTC'))"
"::timestamp < ((now() at time zone 'UTC') - interval %s)"
)
self.env.cr.execute(query, (AsIs(self._table), "%s seconds" % seconds))

193
account_financial_report/report/abstract_report_xlsx.py

@ -1,9 +1,7 @@
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
import datetime
from odoo import models
class AbstractReportXslx(models.AbstractModel):
@ -42,7 +40,7 @@ class AbstractReportXslx(models.AbstractModel):
self._define_formats(workbook)
report_name = self._get_report_name(report)
report_name = self._get_report_name(report, data=data)
report_footer = self._get_report_footer()
filters = self._get_report_filters(report)
self.columns = self._get_report_columns(report)
@ -55,14 +53,13 @@ class AbstractReportXslx(models.AbstractModel):
self._write_filters(filters)
self._generate_report_content(workbook, report)
self._generate_report_content(workbook, report, data)
self._write_report_footer(report_footer)
def _define_formats(self, workbook):
""" Add cell formats to current workbook.
Those formats can be used on all cell.
Available formats are :
* format_bold
* format_right
@ -189,8 +186,6 @@ class AbstractReportXslx(models.AbstractModel):
"""
for col_pos, column in self.columns.items():
value = getattr(line_object, column['field'])
if isinstance(value, datetime.date):
value = fields.Date.to_string(value)
cell_type = column.get('type', 'string')
if cell_type == 'many2one':
self.sheet.write_string(
@ -219,10 +214,49 @@ class AbstractReportXslx(models.AbstractModel):
)
self.row_pos += 1
def write_line_from_dict(self, line_dict):
"""Write a line on current line
"""
for col_pos, column in self.columns.items():
value = line_dict.get(column['field'], False)
cell_type = column.get('type', 'string')
if cell_type == 'string':
if (line_dict.get('account_group_id', False) and
line_dict['account_group_id']):
self.sheet.write_string(
self.row_pos, col_pos, value or '',
self.format_bold)
else:
if not isinstance(value, str) and \
not isinstance(value, bool) and \
not isinstance(value, int):
value = value.strftime("%d/%m/%Y")
self.sheet.write_string(
self.row_pos, col_pos, value or '')
elif cell_type == 'amount':
if line_dict.get('account_group_id', False) and \
line_dict['account_group_id']:
cell_format = self.format_amount_bold
else:
cell_format = self.format_amount
self.sheet.write_number(
self.row_pos, col_pos, float(value), cell_format
)
elif cell_type == 'amount_currency':
if line_dict.get('currency_name', False):
format_amt = self._get_currency_amt_format_dict(
line_dict)
self.sheet.write_number(
self.row_pos, col_pos, float(value), format_amt
)
elif cell_type == 'currency_name':
self.sheet.write_string(
self.row_pos, col_pos, value or '', self.format_right)
self.row_pos += 1
def write_initial_balance(self, my_object, label):
"""Write a specific initial balance line on current line
using defined columns field_initial_balance name.
Columns are defined with `_get_report_columns` method.
"""
col_pos_label = self._get_col_pos_initial_balance_label()
@ -257,10 +291,46 @@ class AbstractReportXslx(models.AbstractModel):
)
self.row_pos += 1
def write_initial_balance_from_dict(self, my_object, label):
"""Write a specific initial balance line on current line
using defined columns field_initial_balance name.
Columns are defined with `_get_report_columns` method.
"""
col_pos_label = self._get_col_pos_initial_balance_label()
self.sheet.write(self.row_pos, col_pos_label, label, self.format_right)
for col_pos, column in self.columns.items():
if column.get('field_initial_balance'):
value = my_object.get(column['field_initial_balance'], False)
cell_type = column.get('type', 'string')
if cell_type == 'string':
self.sheet.write_string(self.row_pos, col_pos, value or '')
elif cell_type == 'amount':
self.sheet.write_number(
self.row_pos, col_pos, float(value), self.format_amount
)
elif cell_type == 'amount_currency':
if my_object['currency_id']:
format_amt = self._get_currency_amt_format(
my_object)
self.sheet.write_number(
self.row_pos, col_pos,
float(value), format_amt
)
elif column.get('field_currency_balance'):
value = my_object.get(column['field_currency_balance'], False)
cell_type = column.get('type', 'string')
if cell_type == 'many2one':
if my_object['currency_id']:
self.sheet.write_string(
self.row_pos, col_pos,
value.name or '',
self.format_right
)
self.row_pos += 1
def write_ending_balance(self, my_object, name, label):
"""Write a specific ending balance line on current line
using defined columns field_final_balance name.
Columns are defined with `_get_report_columns` method.
"""
for i in range(0, len(self.columns)):
@ -305,6 +375,54 @@ class AbstractReportXslx(models.AbstractModel):
)
self.row_pos += 1
def write_ending_balance_from_dict(self, my_object, name, label):
"""Write a specific ending balance line on current line
using defined columns field_final_balance name.
Columns are defined with `_get_report_columns` method.
"""
for i in range(0, len(self.columns)):
self.sheet.write(self.row_pos, i, '', self.format_header_right)
row_count_name = self._get_col_count_final_balance_name()
col_pos_label = self._get_col_pos_final_balance_label()
self.sheet.merge_range(
self.row_pos, 0, self.row_pos, row_count_name - 1, name,
self.format_header_left
)
self.sheet.write(self.row_pos, col_pos_label, label,
self.format_header_right)
for col_pos, column in self.columns.items():
if column.get('field_final_balance'):
value = my_object.get(column['field_final_balance'], False)
cell_type = column.get('type', 'string')
if cell_type == 'string':
self.sheet.write_string(self.row_pos, col_pos,
value or '',
self.format_header_right)
elif cell_type == 'amount':
self.sheet.write_number(
self.row_pos, col_pos, float(value),
self.format_header_amount
)
elif cell_type == 'amount_currency':
if my_object['currency_id'] and value:
format_amt = self._get_currency_amt_format_dict(
my_object)
self.sheet.write_number(
self.row_pos, col_pos, float(value),
format_amt
)
elif column.get('field_currency_balance'):
value = my_object.get(column['field_currency_balance'], False)
cell_type = column.get('type', 'string')
if cell_type == 'many2one':
if my_object['currency_id']:
self.sheet.write_string(
self.row_pos, col_pos,
value or '',
self.format_header_right
)
self.row_pos += 1
def _get_currency_amt_format(self, line_object):
""" Return amount format specific for each currency. """
if hasattr(line_object, 'account_group_id') and \
@ -327,6 +445,30 @@ class AbstractReportXslx(models.AbstractModel):
format_amt.set_num_format(format_amount)
return format_amt
def _get_currency_amt_format_dict(self, line_dict):
""" Return amount format specific for each currency. """
if line_dict.get('account_group_id', False) and \
line_dict['account_group_id']:
format_amt = getattr(self, 'format_amount_bold')
field_prefix = 'format_amount_bold'
else:
format_amt = getattr(self, 'format_amount')
field_prefix = 'format_amount'
if line_dict.get('currency_id', False) and line_dict['currency_id']:
currency = self.env['res.currency'].browse(
[line_dict['currency_id']])
field_name = \
'%s_%s' % (field_prefix, currency.name)
if hasattr(self, field_name):
format_amt = getattr(self, field_name)
else:
format_amt = self.workbook.add_format()
setattr(self, 'field_name', format_amt)
format_amount = \
'#,##0.' + ('0' * currency.decimal_places)
format_amt.set_num_format(format_amount)
return format_amt
def _get_currency_amt_header_format(self, line_object):
""" Return amount header format for each currency. """
format_amt = getattr(self, 'format_header_amount')
@ -346,24 +488,42 @@ class AbstractReportXslx(models.AbstractModel):
format_amt.set_num_format(format_amount)
return format_amt
def _generate_report_content(self, workbook, report):
def _get_currency_amt_header_format_dict(self, line_object):
""" Return amount header format for each currency. """
format_amt = getattr(self, 'format_header_amount')
if line_object['currency_id']:
field_name = \
'format_header_amount_%s' % line_object['currency_name']
if hasattr(self, field_name):
format_amt = getattr(self, field_name)
else:
format_amt = self.workbook.add_format(
{'bold': True,
'border': True,
'bg_color': '#FFFFCC'})
setattr(self, 'field_name', format_amt)
format_amount = \
'#,##0.' + ('0' * line_object['currency_id'].decimal_places)
format_amt.set_num_format(format_amount)
return format_amt
def _generate_report_content(self, workbook, report, data):
"""
Allow to fetch report content to be displayed.
"""
raise NotImplementedError()
def _get_report_complete_name(self, report, prefix):
def _get_report_complete_name(self, report, prefix, data=None):
if report.company_id:
suffix = ' - %s - %s' % (
report.company_id.name, report.company_id.currency_id.name)
return prefix + suffix
return prefix
def _get_report_name(self, report):
def _get_report_name(self, report, data=False):
"""
Allow to define the report name.
Report name will be used as sheet name and as report title.
:return: the report name
"""
raise NotImplementedError()
@ -379,11 +539,8 @@ class AbstractReportXslx(models.AbstractModel):
"""
Allow to define the report columns
which will be used to generate report.
:return: the report columns as dict
:Example:
{
0: {'header': 'Simple column',
'field': 'field_name_on_my_object',
@ -399,9 +556,7 @@ class AbstractReportXslx(models.AbstractModel):
def _get_report_filters(self, report):
"""
:return: the report filters as list
:Example:
[
['first_filter_name', 'first_filter_value'],
['second_filter_name', 'second_filter_value']

971
account_financial_report/report/aged_partner_balance.py

@ -1,633 +1,374 @@
# © 2016 Julien Coux (Camptocamp)
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
from odoo import models, api
from odoo.tools import float_is_zero
from datetime import date, datetime, timedelta
import pandas as pd
class AgedPartnerBalanceReport(models.TransientModel):
""" Here, we just define class fields.
For methods, go more bottom at this file.
The class hierarchy is :
* AgedPartnerBalanceReport
** AgedPartnerBalanceReportAccount
*** AgedPartnerBalanceReportPartner
**** AgedPartnerBalanceReportLine
**** AgedPartnerBalanceReportMoveLine
If "show_move_line_details" is selected
"""
_name = 'report_aged_partner_balance'
_inherit = 'account_financial_report_abstract'
# Filters fields, used for data computation
date_at = fields.Date()
only_posted_moves = fields.Boolean()
company_id = fields.Many2one(comodel_name='res.company')
filter_account_ids = fields.Many2many(comodel_name='account.account')
filter_partner_ids = fields.Many2many(comodel_name='res.partner')
show_move_line_details = fields.Boolean()
# Open Items Report Data fields, used as base for compute the data reports
open_items_id = fields.Many2one(comodel_name='report_open_items')
# Data fields, used to browse report data
account_ids = fields.One2many(
comodel_name='report_aged_partner_balance_account',
inverse_name='report_id'
)
class AgedPartnerBalanceReportAccount(models.TransientModel):
_name = 'report_aged_partner_balance_account'
_inherit = 'account_financial_report_abstract'
_order = 'code ASC'
report_id = fields.Many2one(
comodel_name='report_aged_partner_balance',
ondelete='cascade',
index=True
)
# Data fields, used to keep link with real object
account_id = fields.Many2one(
'account.account',
index=True
)
# Data fields, used for report display
code = fields.Char()
name = fields.Char()
cumul_amount_residual = fields.Float(digits=(16, 2))
cumul_current = fields.Float(digits=(16, 2))
cumul_age_30_days = fields.Float(digits=(16, 2))
cumul_age_60_days = fields.Float(digits=(16, 2))
cumul_age_90_days = fields.Float(digits=(16, 2))
cumul_age_120_days = fields.Float(digits=(16, 2))
cumul_older = fields.Float(digits=(16, 2))
percent_current = fields.Float(digits=(16, 2))
percent_age_30_days = fields.Float(digits=(16, 2))
percent_age_60_days = fields.Float(digits=(16, 2))
percent_age_90_days = fields.Float(digits=(16, 2))
percent_age_120_days = fields.Float(digits=(16, 2))
percent_older = fields.Float(digits=(16, 2))
# Data fields, used to browse report data
partner_ids = fields.One2many(
comodel_name='report_aged_partner_balance_partner',
inverse_name='report_account_id'
)
class AgedPartnerBalanceReportPartner(models.TransientModel):
_name = 'report_aged_partner_balance_partner'
_inherit = 'account_financial_report_abstract'
report_account_id = fields.Many2one(
comodel_name='report_aged_partner_balance_account',
ondelete='cascade',
index=True
)
# Data fields, used to keep link with real object
partner_id = fields.Many2one(
'res.partner',
index=True
)
# Data fields, used for report display
name = fields.Char()
# Data fields, used to browse report data
move_line_ids = fields.One2many(
comodel_name='report_aged_partner_balance_move_line',
inverse_name='report_partner_id'
)
line_ids = fields.One2many(
comodel_name='report_aged_partner_balance_line',
inverse_name='report_partner_id'
)
class AgedPartnerBalanceReport(models.AbstractModel):
_name = 'report.account_financial_report.aged_partner_balance'
@api.model
def _generate_order_by(self, order_spec, query):
"""Custom order to display "No partner allocated" at last position."""
return """
ORDER BY
CASE
WHEN
"report_aged_partner_balance_partner"."partner_id" IS NOT NULL
THEN 0
ELSE 1
END,
"report_aged_partner_balance_partner"."name"
"""
class AgedPartnerBalanceReportLine(models.TransientModel):
_name = 'report_aged_partner_balance_line'
_inherit = 'account_financial_report_abstract'
report_partner_id = fields.Many2one(
comodel_name='report_aged_partner_balance_partner',
ondelete='cascade',
index=True
)
# Data fields, used for report display
partner = fields.Char()
amount_residual = fields.Float(digits=(16, 2))
current = fields.Float(digits=(16, 2))
age_30_days = fields.Float(digits=(16, 2))
age_60_days = fields.Float(digits=(16, 2))
age_90_days = fields.Float(digits=(16, 2))
age_120_days = fields.Float(digits=(16, 2))
older = fields.Float(digits=(16, 2))
class AgedPartnerBalanceReportMoveLine(models.TransientModel):
_name = 'report_aged_partner_balance_move_line'
_inherit = 'account_financial_report_abstract'
report_partner_id = fields.Many2one(
comodel_name='report_aged_partner_balance_partner',
ondelete='cascade',
index=True
)
# Data fields, used to keep link with real object
move_line_id = fields.Many2one('account.move.line')
# Data fields, used for report display
date = fields.Date()
date_due = fields.Date()
entry = fields.Char()
journal = fields.Char()
account = fields.Char()
partner = fields.Char()
label = fields.Char()
def _initialize_account(self, ag_pb_data, acc_id):
ag_pb_data[acc_id] = {}
ag_pb_data[acc_id]['id'] = acc_id
ag_pb_data[acc_id]['residual'] = 0.0
ag_pb_data[acc_id]['current'] = 0.0
ag_pb_data[acc_id]['30_days'] = 0.0
ag_pb_data[acc_id]['60_days'] = 0.0
ag_pb_data[acc_id]['90_days'] = 0.0
ag_pb_data[acc_id]['120_days'] = 0.0
ag_pb_data[acc_id]['older'] = 0.0
return ag_pb_data
amount_residual = fields.Float(digits=(16, 2))
current = fields.Float(digits=(16, 2))
age_30_days = fields.Float(digits=(16, 2))
age_60_days = fields.Float(digits=(16, 2))
age_90_days = fields.Float(digits=(16, 2))
age_120_days = fields.Float(digits=(16, 2))
older = fields.Float(digits=(16, 2))
class AgedPartnerBalanceReportCompute(models.TransientModel):
""" Here, we just define methods.
For class fields, go more top at this file.
"""
@api.model
def _initialize_partner(self, ag_pb_data, acc_id, prt_id):
ag_pb_data[acc_id][prt_id] = {}
ag_pb_data[acc_id][prt_id]['id'] = acc_id
ag_pb_data[acc_id][prt_id]['residual'] = 0.0
ag_pb_data[acc_id][prt_id]['current'] = 0.0
ag_pb_data[acc_id][prt_id]['30_days'] = 0.0
ag_pb_data[acc_id][prt_id]['60_days'] = 0.0
ag_pb_data[acc_id][prt_id]['90_days'] = 0.0
ag_pb_data[acc_id][prt_id]['120_days'] = 0.0
ag_pb_data[acc_id][prt_id]['older'] = 0.0
ag_pb_data[acc_id][prt_id]['move_lines'] = []
return ag_pb_data
def _get_journals_data(self, journals_ids):
journals = self.env['account.journal'].browse(journals_ids)
journals_data = {}
for journal in journals:
journals_data.update({journal.id: {'id': journal.id,
'code': journal.code}})
return journals_data
def _get_accounts_data(self, accounts_ids):
accounts = self.env['account.account'].browse(accounts_ids)
accounts_data = {}
for account in accounts:
accounts_data.update({account.id: {'id': account.id,
'code': account.code,
'name': account.name}})
return accounts_data
_inherit = 'report_aged_partner_balance'
@api.model
def _get_move_lines_domain(self, company_id, account_ids, partner_ids,
only_posted_moves):
domain = [('account_id', 'in', account_ids),
('company_id', '=', company_id),
('reconciled', '=', False)]
if partner_ids:
domain += [('partner_id', 'in', partner_ids)]
if only_posted_moves:
domain += [('move_id.state', '=', 'posted')]
return domain
@api.multi
def print_report(self, report_type):
self.ensure_one()
if report_type == 'xlsx':
report_name = 'a_f_r.report_aged_partner_balance_xlsx'
@api.model
def _calculate_amounts(self, ag_pb_data, acc_id, prt_id, residual,
due_date, date_at_object):
ag_pb_data[acc_id]['residual'] += residual
ag_pb_data[acc_id][prt_id]['residual'] += residual
today = date_at_object
if not due_date or today <= due_date:
ag_pb_data[acc_id]['current'] += residual
ag_pb_data[acc_id][prt_id]['current'] += residual
elif today <= due_date + timedelta(days=30):
ag_pb_data[acc_id]['30_days'] += residual
ag_pb_data[acc_id][prt_id]['30_days'] += residual
elif today <= due_date + timedelta(days=60):
ag_pb_data[acc_id]['60_days'] += residual
ag_pb_data[acc_id][prt_id]['60_days'] += residual
elif today <= due_date + timedelta(days=90):
ag_pb_data[acc_id]['90_days'] += residual
ag_pb_data[acc_id][prt_id]['90_days'] += residual
elif today <= due_date + timedelta(days=120):
ag_pb_data[acc_id]['120_days'] += residual
ag_pb_data[acc_id][prt_id]['120_days'] += residual
else:
report_name = 'account_financial_report.' \
'report_aged_partner_balance_qweb'
report = self.env['ir.actions.report'].search(
[('report_name', '=', report_name),
('report_type', '=', report_type)], limit=1)
return report.report_action(self, config=False)
def _get_html(self):
result = {}
rcontext = {}
context = dict(self.env.context)
report = self.browse(context.get('active_id'))
if report:
rcontext['o'] = report
result['html'] = self.env.ref(
'account_financial_report.report_aged_partner_balance').render(
rcontext)
return result
ag_pb_data[acc_id]['older'] += residual
ag_pb_data[acc_id][prt_id]['older'] += residual
return ag_pb_data
def _get_account_partial_reconciled(self, company_id, date_at_object):
domain = [('max_date', '>=', date_at_object),
('company_id', '=', company_id)]
fields = ['debit_move_id', 'credit_move_id', 'amount']
accounts_partial_reconcile = \
self.env['account.partial.reconcile'].search_read(
domain=domain,
fields=fields
)
debit_amount = {}
credit_amount = {}
for account_partial_reconcile_data in accounts_partial_reconcile:
debit_move_id = account_partial_reconcile_data['debit_move_id'][0]
credit_move_id = account_partial_reconcile_data['credit_move_id'][0]
if debit_move_id not in debit_amount.keys():
debit_amount[debit_move_id] = 0.0
debit_amount[debit_move_id] += \
account_partial_reconcile_data['amount']
if credit_move_id not in credit_amount.keys():
credit_amount[credit_move_id] = 0.0
credit_amount[credit_move_id] += \
account_partial_reconcile_data['amount']
account_partial_reconcile_data.update({
'debit_move_id': debit_move_id,
'credit_move_id': credit_move_id,
})
return accounts_partial_reconcile, debit_amount, credit_amount
@api.model
def get_html(self, given_context=None):
return self._get_html()
def _prepare_report_open_items(self):
self.ensure_one()
return {
'date_at': self.date_at,
'only_posted_moves': self.only_posted_moves,
'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.filter_account_ids.ids)],
'filter_partner_ids': [(6, 0, self.filter_partner_ids.ids)],
}
@api.multi
def compute_data_for_report(self):
self.ensure_one()
# Compute Open Items Report Data.
# The data of Aged Partner Balance Report
# are based on Open Items Report data.
model = self.env['report_open_items']
self.open_items_id = model.create(self._prepare_report_open_items())
self.open_items_id.compute_data_for_report()
# Compute report data
self._inject_account_values()
self._inject_partner_values()
self._inject_line_values()
self._inject_line_values(only_empty_partner_line=True)
if self.show_move_line_details:
self._inject_move_line_values()
self._inject_move_line_values(only_empty_partner_line=True)
self._compute_accounts_cumul()
# Refresh cache because all data are computed with SQL requests
self.invalidate_cache()
def _inject_account_values(self):
"""Inject report values for report_aged_partner_balance_account"""
query_inject_account = """
INSERT INTO
report_aged_partner_balance_account
(
report_id,
create_uid,
create_date,
account_id,
code,
name
)
SELECT
%s AS report_id,
%s AS create_uid,
NOW() AS create_date,
rao.account_id,
rao.code,
rao.name
FROM
report_open_items_account rao
WHERE
rao.report_id = %s
"""
query_inject_account_params = (
self.id,
self.env.uid,
self.open_items_id.id,
def _get_new_move_lines_domain(self, new_ml_ids, account_ids, company_id,
partner_ids, only_posted_moves):
domain = [('account_id', 'in', account_ids),
('company_id', '=', company_id),
('id', 'in', new_ml_ids)]
if partner_ids:
domain += [('partner_id', 'in', partner_ids)]
if only_posted_moves:
domain += [('move_id.state', '=', 'posted')]
return domain
def _recalculate_move_lines(self, move_lines, debit_ids, credit_ids,
debit_amount, credit_amount, ml_ids,
account_ids, company_id, partner_ids,
only_posted_moves):
reconciled_ids = list(debit_ids) + list(credit_ids)
new_ml_ids = []
for reconciled_id in reconciled_ids:
if reconciled_id not in ml_ids and reconciled_id not in new_ml_ids:
new_ml_ids += [reconciled_id]
new_domain = self._get_new_move_lines_domain(new_ml_ids, account_ids,
company_id, partner_ids,
only_posted_moves)
ml_fields = [
'id', 'name', 'date', 'move_id', 'journal_id', 'account_id',
'partner_id', 'amount_residual', 'date_maturity', 'ref',
'reconciled']
new_move_lines = self.env['account.move.line'].search_read(
domain=new_domain, fields=ml_fields
)
self.env.cr.execute(query_inject_account, query_inject_account_params)
def _inject_partner_values(self):
"""Inject report values for report_aged_partner_balance_partner"""
query_inject_partner = """
INSERT INTO
report_aged_partner_balance_partner
(
report_account_id,
create_uid,
create_date,
partner_id,
name
)
SELECT
ra.id AS report_account_id,
%s AS create_uid,
NOW() AS create_date,
rpo.partner_id,
rpo.name
FROM
report_open_items_partner rpo
INNER JOIN
report_open_items_account rao ON rpo.report_account_id = rao.id
INNER JOIN
report_aged_partner_balance_account ra ON rao.code = ra.code
WHERE
rao.report_id = %s
AND ra.report_id = %s
"""
query_inject_partner_params = (
self.env.uid,
self.open_items_id.id,
self.id,
move_lines = move_lines + new_move_lines
for move_line in move_lines:
ml_id = move_line['id']
if ml_id in debit_ids:
move_line['amount_residual'] += debit_amount[ml_id]
if ml_id in credit_ids:
move_line['amount_residual'] -= credit_amount[ml_id]
return move_lines
def _get_move_lines_data(
self, company_id, account_ids, partner_ids, date_at_object,
only_posted_moves, show_move_line_details):
domain = self._get_move_lines_domain(company_id, account_ids,
partner_ids, only_posted_moves)
ml_fields = [
'id', 'name', 'date', 'move_id', 'journal_id', 'account_id',
'partner_id', 'amount_residual', 'date_maturity', 'ref',
'reconciled']
move_lines = self.env['account.move.line'].search_read(
domain=domain, fields=ml_fields
)
self.env.cr.execute(query_inject_partner, query_inject_partner_params)
def _inject_line_values(self, only_empty_partner_line=False):
""" Inject report values for report_aged_partner_balance_line.
ml_ids = set(pd.DataFrame(move_lines).id.to_list())
journals_ids = set()
partners_ids = set()
partners_data = {}
ag_pb_data = {}
if date_at_object < date.today():
acc_partial_rec, debit_amount, credit_amount = \
self._get_account_partial_reconciled(company_id, date_at_object)
if acc_partial_rec:
acc_partial_rec_data = pd.DataFrame(acc_partial_rec)
debit_ids = set(acc_partial_rec_data.debit_move_id.to_list())
credit_ids = set(acc_partial_rec_data.credit_move_id.to_list())
move_lines = self._recalculate_move_lines(
move_lines, debit_ids, credit_ids,
debit_amount, credit_amount, ml_ids, account_ids,
company_id, partner_ids, only_posted_moves
)
moves_lines_to_remove = []
for move_line in move_lines:
if move_line['date'] > date_at_object or \
float_is_zero(move_line['amount_residual'],
precision_digits=2):
moves_lines_to_remove.append(move_line)
if len(moves_lines_to_remove) > 0:
for move_line_to_remove in moves_lines_to_remove:
move_lines.remove(move_line_to_remove)
for move_line in move_lines:
journals_ids.add(move_line['journal_id'][0])
acc_id = move_line['account_id'][0]
if move_line['partner_id']:
prt_id = move_line['partner_id'][0]
prt_name = move_line['partner_id'][1]
else:
prt_id = 0
prt_name = ""
if prt_id not in partners_ids:
partners_data.update({
prt_id: {'id': prt_id, 'name': prt_name}
})
partners_ids.add(prt_id)
if acc_id not in ag_pb_data.keys():
ag_pb_data = self._initialize_account(ag_pb_data, acc_id)
if prt_id not in ag_pb_data[acc_id]:
ag_pb_data = self._initialize_partner(ag_pb_data, acc_id,
prt_id)
move_line_data = {}
if show_move_line_details:
move_line_data.update({
'date': move_line['date'],
'entry': move_line['move_id'][1],
'jnl_id': move_line['journal_id'][0],
'acc_id': acc_id,
'partner': prt_name,
'ref': move_line['ref'],
'due_date': move_line['date_maturity'],
'residual': move_line['amount_residual'],
})
ag_pb_data[acc_id][prt_id]['move_lines'].append(move_line_data)
ag_pb_data = self._calculate_amounts(
ag_pb_data, acc_id, prt_id, move_line['amount_residual'],
move_line['date_maturity'], date_at_object)
journals_data = self._get_journals_data(list(journals_ids))
accounts_data = self._get_accounts_data(ag_pb_data.keys())
return ag_pb_data, accounts_data, partners_data, journals_data
The "only_empty_partner_line" value is used
to compute data without partner.
"""
query_inject_line = """
WITH
date_range AS
(
SELECT
DATE %s AS date_current,
DATE %s - INTEGER '30' AS date_less_30_days,
DATE %s - INTEGER '60' AS date_less_60_days,
DATE %s - INTEGER '90' AS date_less_90_days,
DATE %s - INTEGER '120' AS date_less_120_days
)
INSERT INTO
report_aged_partner_balance_line
(
report_partner_id,
create_uid,
create_date,
partner,
amount_residual,
current,
age_30_days,
age_60_days,
age_90_days,
age_120_days,
older
)
SELECT
rp.id AS report_partner_id,
%s AS create_uid,
NOW() AS create_date,
rp.name,
SUM(rlo.amount_residual) AS amount_residual,
SUM(
CASE
WHEN rlo.date_due >= date_range.date_current
THEN rlo.amount_residual
END
) AS current,
SUM(
CASE
WHEN
rlo.date_due >= date_range.date_less_30_days
AND rlo.date_due < date_range.date_current
THEN rlo.amount_residual
END
) AS age_30_days,
SUM(
CASE
WHEN
rlo.date_due >= date_range.date_less_60_days
AND rlo.date_due < date_range.date_less_30_days
THEN rlo.amount_residual
END
) AS age_60_days,
SUM(
CASE
WHEN
rlo.date_due >= date_range.date_less_90_days
AND rlo.date_due < date_range.date_less_60_days
THEN rlo.amount_residual
END
) AS age_90_days,
SUM(
CASE
WHEN
rlo.date_due >= date_range.date_less_120_days
AND rlo.date_due < date_range.date_less_90_days
THEN rlo.amount_residual
END
) AS age_120_days,
SUM(
CASE
WHEN rlo.date_due < date_range.date_less_120_days
THEN rlo.amount_residual
END
) AS older
FROM
date_range,
report_open_items_move_line rlo
INNER JOIN
report_open_items_partner rpo ON rlo.report_partner_id = rpo.id
INNER JOIN
report_open_items_account rao ON rpo.report_account_id = rao.id
INNER JOIN
report_aged_partner_balance_account ra ON rao.code = ra.code
INNER JOIN
report_aged_partner_balance_partner rp
ON
ra.id = rp.report_account_id
"""
if not only_empty_partner_line:
query_inject_line += """
AND rpo.partner_id = rp.partner_id
"""
elif only_empty_partner_line:
query_inject_line += """
AND rpo.partner_id IS NULL
AND rp.partner_id IS NULL
"""
query_inject_line += """
WHERE
rao.report_id = %s
AND ra.report_id = %s
GROUP BY
rp.id
"""
query_inject_line_params = (self.date_at,) * 5
query_inject_line_params += (
self.env.uid,
self.open_items_id.id,
self.id,
)
self.env.cr.execute(query_inject_line, query_inject_line_params)
def _inject_move_line_values(self, only_empty_partner_line=False):
""" Inject report values for report_aged_partner_balance_move_line
@api.model
def _compute_maturity_date(self, ml, date_at_object):
ml.update({
'current': 0.0,
'30_days': 0.0,
'60_days': 0.0,
'90_days': 0.0,
'120_days': 0.0,
'older': 0.0,
})
due_date = ml['due_date']
amount = ml['residual']
today = date_at_object
if not due_date or today <= due_date:
ml['current'] += amount
elif today <= due_date + timedelta(days=30):
ml['30_days'] += amount
elif today <= due_date + timedelta(days=60):
ml['60_days'] += amount
elif today <= due_date + timedelta(days=90):
ml['90_days'] += amount
elif today <= due_date + timedelta(days=120):
ml['120_days'] += amount
else:
ml['older'] += amount
def _create_account_list(
self, ag_pb_data, accounts_data, partners_data, journals_data,
show_move_line_details, date_at_oject):
aged_partner_data = []
for account in accounts_data.values():
acc_id = account['id']
account.update({
'residual': ag_pb_data[acc_id]['residual'],
'current': ag_pb_data[acc_id]['current'],
'30_days': ag_pb_data[acc_id]['30_days'],
'60_days': ag_pb_data[acc_id]['60_days'],
'90_days': ag_pb_data[acc_id]['90_days'],
'120_days': ag_pb_data[acc_id]['120_days'],
'older': ag_pb_data[acc_id]['older'],
'partners': [],
})
for prt_id in ag_pb_data[acc_id]:
if isinstance(prt_id, int):
partner = {
'name': partners_data[prt_id]['name'],
'residual': ag_pb_data[acc_id][prt_id]['residual'],
'current': ag_pb_data[acc_id][prt_id]['current'],
'30_days': ag_pb_data[acc_id][prt_id]['30_days'],
'60_days': ag_pb_data[acc_id][prt_id]['60_days'],
'90_days': ag_pb_data[acc_id][prt_id]['90_days'],
'120_days': ag_pb_data[acc_id][prt_id]['120_days'],
'older': ag_pb_data[acc_id][prt_id]['older'],
}
if show_move_line_details:
move_lines = []
for ml in ag_pb_data[acc_id][prt_id]['move_lines']:
ml.update({
'journal': journals_data[ml['jnl_id']]['code'],
'account': accounts_data[ml['acc_id']]['code'],
})
self._compute_maturity_date(ml, date_at_oject)
move_lines.append(ml)
partner.update({
'move_lines': move_lines
})
account['partners'].append(partner)
aged_partner_data.append(account)
return aged_partner_data
The "only_empty_partner_line" value is used
to compute data without partner.
"""
query_inject_move_line = """
WITH
date_range AS
(
SELECT
DATE %s AS date_current,
DATE %s - INTEGER '30' AS date_less_30_days,
DATE %s - INTEGER '60' AS date_less_60_days,
DATE %s - INTEGER '90' AS date_less_90_days,
DATE %s - INTEGER '120' AS date_less_120_days
)
INSERT INTO
report_aged_partner_balance_move_line
(
report_partner_id,
create_uid,
create_date,
move_line_id,
date,
date_due,
entry,
journal,
account,
partner,
label,
amount_residual,
current,
age_30_days,
age_60_days,
age_90_days,
age_120_days,
older
)
SELECT
rp.id AS report_partner_id,
%s AS create_uid,
NOW() AS create_date,
rlo.move_line_id,
rlo.date,
rlo.date_due,
rlo.entry,
rlo.journal,
rlo.account,
rlo.partner,
rlo.label,
rlo.amount_residual AS amount_residual,
CASE
WHEN rlo.date_due >= date_range.date_current
THEN rlo.amount_residual
END AS current,
CASE
WHEN
rlo.date_due >= date_range.date_less_30_days
AND rlo.date_due < date_range.date_current
THEN rlo.amount_residual
END AS age_30_days,
CASE
WHEN
rlo.date_due >= date_range.date_less_60_days
AND rlo.date_due < date_range.date_less_30_days
THEN rlo.amount_residual
END AS age_60_days,
CASE
WHEN
rlo.date_due >= date_range.date_less_90_days
AND rlo.date_due < date_range.date_less_60_days
THEN rlo.amount_residual
END AS age_90_days,
CASE
WHEN
rlo.date_due >= date_range.date_less_120_days
AND rlo.date_due < date_range.date_less_90_days
THEN rlo.amount_residual
END AS age_120_days,
CASE
WHEN rlo.date_due < date_range.date_less_120_days
THEN rlo.amount_residual
END AS older
FROM
date_range,
report_open_items_move_line rlo
INNER JOIN
report_open_items_partner rpo ON rlo.report_partner_id = rpo.id
INNER JOIN
report_open_items_account rao ON rpo.report_account_id = rao.id
INNER JOIN
report_aged_partner_balance_account ra ON rao.code = ra.code
INNER JOIN
report_aged_partner_balance_partner rp
ON
ra.id = rp.report_account_id
"""
if not only_empty_partner_line:
query_inject_move_line += """
AND rpo.partner_id = rp.partner_id
"""
elif only_empty_partner_line:
query_inject_move_line += """
AND rpo.partner_id IS NULL
AND rp.partner_id IS NULL
"""
query_inject_move_line += """
WHERE
rao.report_id = %s
AND ra.report_id = %s
"""
query_inject_move_line_params = (self.date_at,) * 5
query_inject_move_line_params += (
self.env.uid,
self.open_items_id.id,
self.id,
)
self.env.cr.execute(query_inject_move_line,
query_inject_move_line_params)
@api.model
def _calculate_percent(self, aged_partner_data):
for account in aged_partner_data:
if abs(account['residual']) > 0.01:
total = account['residual']
account.update({
'percent_current': abs(
round((account['current'] / total) * 100, 2)),
'percent_30_days': abs(
round((account['30_days'] / total) * 100,
2)),
'percent_60_days': abs(
round((account['60_days'] / total) * 100,
2)),
'percent_90_days': abs(
round((account['90_days'] / total) * 100,
2)),
'percent_120_days': abs(
round((account['120_days'] / total) * 100,
2)),
'percent_older': abs(
round((account['older'] / total) * 100, 2)),
})
else:
account.update({
'percent_current': 0.0,
'percent_30_days': 0.0,
'percent_60_days': 0.0,
'percent_90_days': 0.0,
'percent_120_days': 0.0,
'percent_older': 0.0,
})
return aged_partner_data
def _compute_accounts_cumul(self):
""" Compute cumulative amount for
report_aged_partner_balance_account.
"""
query_compute_accounts_cumul = """
WITH
cumuls AS
(
SELECT
ra.id AS report_account_id,
SUM(rl.amount_residual) AS cumul_amount_residual,
SUM(rl.current) AS cumul_current,
SUM(rl.age_30_days) AS cumul_age_30_days,
SUM(rl.age_60_days) AS cumul_age_60_days,
SUM(rl.age_90_days) AS cumul_age_90_days,
SUM(rl.age_120_days) AS cumul_age_120_days,
SUM(rl.older) AS cumul_older
FROM
report_aged_partner_balance_line rl
INNER JOIN
report_aged_partner_balance_partner rp
ON rl.report_partner_id = rp.id
INNER JOIN
report_aged_partner_balance_account ra
ON rp.report_account_id = ra.id
WHERE
ra.report_id = %s
GROUP BY
ra.id
)
UPDATE
report_aged_partner_balance_account
SET
cumul_amount_residual = c.cumul_amount_residual,
cumul_current = c.cumul_current,
cumul_age_30_days = c.cumul_age_30_days,
cumul_age_60_days = c.cumul_age_60_days,
cumul_age_90_days = c.cumul_age_90_days,
cumul_age_120_days = c.cumul_age_120_days,
cumul_older = c.cumul_older,
percent_current =
CASE
WHEN c.cumul_amount_residual != 0
THEN 100 * c.cumul_current / c.cumul_amount_residual
END,
percent_age_30_days =
CASE
WHEN c.cumul_amount_residual != 0
THEN 100 * c.cumul_age_30_days / c.cumul_amount_residual
END,
percent_age_60_days =
CASE
WHEN c.cumul_amount_residual != 0
THEN 100 * c.cumul_age_60_days / c.cumul_amount_residual
END,
percent_age_90_days =
CASE
WHEN c.cumul_amount_residual != 0
THEN 100 * c.cumul_age_90_days / c.cumul_amount_residual
END,
percent_age_120_days =
CASE
WHEN c.cumul_amount_residual != 0
THEN 100 * c.cumul_age_120_days / c.cumul_amount_residual
END,
percent_older =
CASE
WHEN c.cumul_amount_residual != 0
THEN 100 * c.cumul_older / c.cumul_amount_residual
END
FROM
cumuls c
WHERE
id = c.report_account_id
"""
params_compute_accounts_cumul = (self.id,)
self.env.cr.execute(query_compute_accounts_cumul,
params_compute_accounts_cumul)
@api.multi
def _get_report_values(self, docids, data):
wizard_id = data['wizard_id']
company = self.env['res.company'].browse(data['company_id'])
company_id = data['company_id']
account_ids = data['account_ids']
partner_ids = data['partner_ids']
date_at = data['date_at']
date_at_object = datetime.strptime(date_at, '%Y-%m-%d').date()
only_posted_moves = data['only_posted_moves']
show_move_line_details = data['show_move_line_details']
ag_pb_data, accounts_data, partners_data, \
journals_data = self._get_move_lines_data(
company_id, account_ids, partner_ids, date_at_object,
only_posted_moves, show_move_line_details)
aged_partner_data = self._create_account_list(
ag_pb_data, accounts_data, partners_data, journals_data,
show_move_line_details, date_at_object)
aged_partner_data = self._calculate_percent(aged_partner_data)
return {
'doc_ids': [wizard_id],
'doc_model': 'open.items.report.wizard',
'docs': self.env['open.items.report.wizard'].browse(wizard_id),
'company_name': company.display_name,
'currency_name': company.currency_id.name,
'date_at': date_at,
'only_posted_moves': only_posted_moves,
'aged_partner_balance': aged_partner_data,
'show_move_lines_details': show_move_line_details,
}

181
account_financial_report/report/aged_partner_balance_xlsx.py

@ -10,52 +10,58 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
_name = 'report.a_f_r.report_aged_partner_balance_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
def _get_report_name(self, report):
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('Aged Partner Balance')
return self._get_report_complete_name(report, report_name)
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
if not report.show_move_line_details:
return {
0: {'header': _('Partner'), 'field': 'partner', 'width': 70},
0: {'header': _('Partner'), 'field': 'name', 'width': 70},
1: {'header': _('Residual'),
'field': 'amount_residual',
'field_footer_total': 'cumul_amount_residual',
'field': 'residual',
'field_footer_total': 'residual',
'type': 'amount',
'width': 14},
2: {'header': _('Current'),
'field': 'current',
'field_footer_total': 'cumul_current',
'field_footer_total': 'current',
'field_footer_percent': 'percent_current',
'type': 'amount',
'width': 14},
3: {'header': _(u'Age ≤ 30 d.'),
'field': 'age_30_days',
'field_footer_total': 'cumul_age_30_days',
'field_footer_percent': 'percent_age_30_days',
'field': '30_days',
'field_footer_total': '30_days',
'field_footer_percent': 'percent_30_days',
'type': 'amount',
'width': 14},
4: {'header': _(u'Age ≤ 60 d.'),
'field': 'age_60_days',
'field_footer_total': 'cumul_age_60_days',
'field_footer_percent': 'percent_age_60_days',
'field': '60_days',
'field_footer_total': '60_days',
'field_footer_percent': 'percent_60_days',
'type': 'amount',
'width': 14},
5: {'header': _(u'Age ≤ 90 d.'),
'field': 'age_90_days',
'field_footer_total': 'cumul_age_90_days',
'field_footer_percent': 'percent_age_90_days',
'field': '90_days',
'field_footer_total': '90_days',
'field_footer_percent': 'percent_90_days',
'type': 'amount',
'width': 14},
6: {'header': _(u'Age ≤ 120 d.'),
'field': 'age_120_days',
'field_footer_total': 'cumul_age_120_days',
'field_footer_percent': 'percent_age_120_days',
'field': '120_days',
'field_footer_total': '120_days',
'field_footer_percent': 'percent_120_days',
'type': 'amount',
'width': 14},
7: {'header': _('Older'),
'field': 'older',
'field_footer_total': 'cumul_older',
'field_footer_total': 'older',
'field_footer_percent': 'percent_older',
'type': 'amount',
'width': 14},
@ -66,52 +72,52 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
3: {'header': _('Account'), 'field': 'account', 'width': 9},
4: {'header': _('Partner'), 'field': 'partner', 'width': 25},
5: {'header': _('Ref - Label'), 'field': 'label', 'width': 40},
6: {'header': _('Due date'), 'field': 'date_due', 'width': 11},
5: {'header': _('Ref - Label'), 'field': 'ref', 'width': 40},
6: {'header': _('Due date'), 'field': 'due_date', 'width': 11},
7: {'header': _('Residual'),
'field': 'amount_residual',
'field_footer_total': 'cumul_amount_residual',
'field_final_balance': 'amount_residual',
'field': 'residual',
'field_footer_total': 'residual',
'field_final_balance': 'residual',
'type': 'amount',
'width': 14},
8: {'header': _('Current'),
'field': 'current',
'field_footer_total': 'cumul_current',
'field_footer_total': 'current',
'field_footer_percent': 'percent_current',
'field_final_balance': 'current',
'type': 'amount',
'width': 14},
9: {'header': _(u'Age ≤ 30 d.'),
'field': 'age_30_days',
'field_footer_total': 'cumul_age_30_days',
'field_footer_percent': 'percent_age_30_days',
'field_final_balance': 'age_30_days',
'field': '30_days',
'field_footer_total': '30_days',
'field_footer_percent': 'percent_30_days',
'field_final_balance': '30_days',
'type': 'amount',
'width': 14},
10: {'header': _(u'Age ≤ 60 d.'),
'field': 'age_60_days',
'field_footer_total': 'cumul_age_60_days',
'field_footer_percent': 'percent_age_60_days',
'field_final_balance': 'age_60_days',
'field': '60_days',
'field_footer_total': '60_days',
'field_footer_percent': 'percent_60_days',
'field_final_balance': '60_days',
'type': 'amount',
'width': 14},
11: {'header': _(u'Age ≤ 90 d.'),
'field': 'age_90_days',
'field_footer_total': 'cumul_age_90_days',
'field_footer_percent': 'percent_age_90_days',
'field_final_balance': 'age_90_days',
'field': '90_days',
'field_footer_total': '90_days',
'field_footer_percent': 'percent_90_days',
'field_final_balance': '90_days',
'type': 'amount',
'width': 14},
12: {'header': _(u'Age ≤ 120 d.'),
'field': 'age_120_days',
'field_footer_total': 'cumul_age_120_days',
'field_footer_percent': 'percent_age_120_days',
'field_final_balance': 'age_120_days',
'field': '120_days',
'field_footer_total': '120_days',
'field_footer_percent': 'percent_120_days',
'field_final_balance': '120_days',
'type': 'amount',
'width': 14},
13: {'header': _('Older'),
'field': 'older',
'field_footer_total': 'cumul_older',
'field_footer_total': 'older',
'field_footer_percent': 'percent_older',
'field_final_balance': 'older',
'type': 'amount',
@ -120,9 +126,9 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
def _get_report_filters(self, report):
return [
[_('Date at filter'), report.date_at],
[_('Date at filter'), report.date_at.strftime("%d/%m/%Y")],
[_('Target moves filter'),
_('All posted entries') if report.only_posted_moves else _(
_('All posted entries') if report.target_move == 'posted' else _(
'All entries')],
]
@ -141,94 +147,89 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
def _get_col_pos_final_balance_label(self):
return 5
def _generate_report_content(self, workbook, report):
if not report.show_move_line_details:
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.aged_partner_balance'
]._get_report_values(report, data)
show_move_line_details = res_data['show_move_lines_details']
aged_partner_balance = res_data['aged_partner_balance']
if not show_move_line_details:
# For each account
for account in report.account_ids:
for account in aged_partner_balance:
# Write account title
self.write_array_title(account.code + ' - ' + account.name)
self.write_array_title(account['code'] + ' - ' + account[
'name'])
# Display array header for partners lines
self.write_array_header()
# Display partner lines
for partner in account.partner_ids:
self.write_line(partner.line_ids)
for partner in account['partners']:
self.write_line_from_dict(partner)
# Display account lines
self.write_account_footer(report,
account,
_('Total'),
'field_footer_total',
self.format_header_right,
self.format_header_amount,
False)
self.write_account_footer(report,
account,
_('Percents'),
'field_footer_percent',
self.format_right_bold_italic,
self.format_percent_bold_italic,
True)
self.write_account_footer_from_dict(
report, account, ('Total'), 'field_footer_total',
self.format_header_right, self.format_header_amount, False)
self.write_account_footer_from_dict(
report, account, ('Percents'), 'field_footer_percent',
self.format_right_bold_italic,
self.format_percent_bold_italic, True)
# 2 lines break
self.row_pos += 2
else:
# For each account
for account in report.account_ids:
for account in aged_partner_balance:
# Write account title
self.write_array_title(account.code + ' - ' + account.name)
self.write_array_title(account['code'] + ' - ' + account[
'name'])
# For each partner
for partner in account.partner_ids:
for partner in account['partners']:
# Write partner title
self.write_array_title(partner.name)
self.write_array_title(partner['name'])
# Display array header for move lines
self.write_array_header()
# Display account move lines
for line in partner.move_line_ids:
self.write_line(line)
for line in partner['move_lines']:
self.write_line_from_dict(line)
# Display ending balance line for partner
self.write_ending_balance(partner.line_ids)
self.write_ending_balance_from_dict(partner)
# Line break
self.row_pos += 1
# Display account lines
self.write_account_footer(report,
account,
_('Total'),
'field_footer_total',
self.format_header_right,
self.format_header_amount,
False)
self.write_account_footer(report,
account,
_('Percents'),
'field_footer_percent',
self.format_right_bold_italic,
self.format_percent_bold_italic,
True)
self.write_account_footer_from_dict(
report, account, ('Total'), 'field_footer_total',
self.format_header_right, self.format_header_amount, False)
self.write_account_footer_from_dict(
report, account, ('Percents'), 'field_footer_percent',
self.format_right_bold_italic,
self.format_percent_bold_italic, True)
# 2 lines break
self.row_pos += 2
def write_ending_balance(self, my_object):
def write_ending_balance_from_dict(self, my_object):
"""
Specific function to write ending partner balance
for Aged Partner Balance
"""
name = None
label = _('Partner cumul aged balance')
super(AgedPartnerBalanceXslx, self).write_ending_balance(
super(AgedPartnerBalanceXslx, self).write_ending_balance_from_dict(
my_object, name, label
)
def write_account_footer(self, report, account, label, field_name,
string_format, amount_format, amount_is_percent):
def write_account_footer_from_dict(
self, report, account, label, field_name, string_format,
amount_format, amount_is_percent):
"""
Specific function to write account footer for Aged Partner Balance
"""
@ -238,7 +239,7 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
if col_pos == col_pos_footer_label:
value = label
else:
value = getattr(account, column[field_name])
value = account.get(column[field_name], False)
cell_type = column.get('type', 'string')
if cell_type == 'string' or col_pos == col_pos_footer_label:
self.sheet.write_string(self.row_pos, col_pos, value or '',

2334
account_financial_report/report/general_ledger.py
File diff suppressed because it is too large
View File

176
account_financial_report/report/general_ledger_xlsx.py

@ -11,9 +11,15 @@ class GeneralLedgerXslx(models.AbstractModel):
_name = 'report.a_f_r.report_general_ledger_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
def _get_report_name(self, report):
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('General Ledger')
return self._get_report_complete_name(report, report_name)
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
res = {
@ -24,15 +30,15 @@ class GeneralLedgerXslx(models.AbstractModel):
4: {'header': _('Taxes'),
'field': 'taxes_description',
'width': 15},
5: {'header': _('Partner'), 'field': 'partner', 'width': 25},
6: {'header': _('Ref - Label'), 'field': 'label', 'width': 40},
5: {'header': _('Partner'), 'field': 'partner_name', 'width': 25},
6: {'header': _('Ref - Label'), 'field': 'ref', 'width': 40},
7: {'header': _('Cost center'),
'field': 'cost_center',
'width': 15},
8: {'header': _('Tags'),
'field': 'tags',
'width': 10},
9: {'header': _('Rec.'), 'field': 'matching_number', 'width': 5},
9: {'header': _('Rec.'), 'field': 'rec_name', 'width': 5},
10: {'header': _('Debit'),
'field': 'debit',
'field_initial_balance': 'initial_debit',
@ -46,7 +52,7 @@ class GeneralLedgerXslx(models.AbstractModel):
'type': 'amount',
'width': 14},
12: {'header': _('Cumul. Bal.'),
'field': 'cumul_balance',
'field': 'balance',
'field_initial_balance': 'initial_balance',
'field_final_balance': 'final_balance',
'type': 'amount',
@ -55,15 +61,15 @@ class GeneralLedgerXslx(models.AbstractModel):
if report.foreign_currency:
foreign_currency = {
13: {'header': _('Cur.'),
'field': 'currency_id',
'field_currency_balance': 'currency_id',
'type': 'many2one', 'width': 7},
'field': 'currency_name',
'field_currency_balance': 'currency_name',
'type': 'currency_name', 'width': 7},
14: {'header': _('Amount cur.'),
'field': 'amount_currency',
'field': 'bal_curr',
'field_initial_balance':
'initial_balance_foreign_currency',
'initial_bal_curr',
'field_final_balance':
'final_balance_foreign_currency',
'final_bal_curr',
'type': 'amount_currency',
'width': 14},
}
@ -78,8 +84,8 @@ class GeneralLedgerXslx(models.AbstractModel):
],
[
_('Target moves filter'),
_('All posted entries') if report.only_posted_moves
else _('All entries'),
_('All posted entries') if report.target_move == 'all' else _(
'All entries'),
],
[
_('Account balance at 0 filter'),
@ -114,71 +120,161 @@ class GeneralLedgerXslx(models.AbstractModel):
def _get_col_pos_final_balance_label(self):
return 5
def _generate_report_content(self, workbook, report):
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.general_ledger'
]._get_report_values(report, data)
general_ledger = res_data['general_ledger']
accounts_data = res_data['accounts_data']
partners_data = res_data['partners_data']
journals_data = res_data['journals_data']
taxes_data = res_data['taxes_data']
tags_data = res_data['tags_data']
filter_partner_ids = res_data['filter_partner_ids']
foreign_currency = res_data['foreign_currency']
# For each account
for account in report.account_ids:
for account in general_ledger:
# Write account title
self.write_array_title(account.code + ' - ' + account.name)
self.write_array_title(account['code'] + ' - ' + accounts_data[
account['id']]['name'])
if not account.partner_ids:
if not account['partners']:
# Display array header for move lines
self.write_array_header()
# Display initial balance line for account
self.write_initial_balance(account)
account.update({
'initial_debit': account['init_bal']['debit'],
'initial_credit': account['init_bal']['credit'],
'initial_balance': account['init_bal']['balance'],
})
if foreign_currency:
account.update({
'initial_bal_curr': account['init_bal']['bal_curr'],
})
self.write_initial_balance_from_dict(account)
# Display account move lines
for line in account.move_line_ids:
self.write_line(line)
for line in account['move_lines']:
line.update({
'account': account['code'],
'journal': journals_data[line['journal_id']]['code'],
})
if line['currency_id']:
line.update({
'currency_name': line['currency_id'][1],
'currency_id': line['currency_id'][0],
})
if line['ref'] != 'Centralized entries':
taxes_description = ""
tags = ""
for tax_id in line['tax_ids']:
taxes_description += str(taxes_data[tax_id][
'amount'])+" "+taxes_data[tax_id]['string']+" "
for tag_id in line['tag_ids']:
tags += tags_data[tag_id]['name']+" "
line.update({
'taxes_description': taxes_description,
'tags': tags,
})
self.write_line_from_dict(line)
else:
# For each partner
for partner in account.partner_ids:
for partner in account['list_partner']:
# Write partner title
self.write_array_title(partner.name)
self.write_array_title(partners_data[partner['id']]['name'])
# Display array header for move lines
self.write_array_header()
# Display initial balance line for partner
self.write_initial_balance(partner)
partner.update({
'initial_debit': partner['init_bal']['debit'],
'initial_credit': partner['init_bal']['credit'],
'initial_balance': partner['init_bal']['balance'],
'name': partners_data[partner['id']]['name'],
'type': 'partner',
'currency_id': accounts_data[account['id']][
'currency_id'],
})
if foreign_currency:
partner.update({
'initial_bal_culrr': partner['init_bal'][
'bal_curr'],
})
self.write_initial_balance_from_dict(partner)
# Display account move lines
for line in partner.move_line_ids:
self.write_line(line)
for line in partner['move_lines']:
line.update({
'account': account['code'],
'journal': journals_data[line['journal_id']]['code']
})
if line['ref'] != 'Centralized entries':
taxes_description = ""
tags = ""
for tax_id in line['tax_ids']:
taxes_description += \
str(taxes_data[tax_id]['amount']) + " " + \
taxes_data[tax_id]['string'] + " "
for tag_id in line['tag_ids']:
tags += tags_data[tag_id]['name'] + " "
line.update({
'taxes_description': taxes_description,
'tags': tags,
})
self.write_line_from_dict(line)
# Display ending balance line for partner
self.write_ending_balance(partner)
partner.update({
'final_debit': partner['fin_bal']['debit'],
'final_credit': partner['fin_bal']['credit'],
'final_balance': partner['fin_bal']['balance'],
})
if foreign_currency:
partner.update({
'final_bal_curr': partner['fin_bal']['bal_curr'],
})
self.write_ending_balance_from_dict(partner)
# Line break
self.row_pos += 1
# Display ending balance line for account
if not report.filter_partner_ids:
self.write_ending_balance(account)
if not filter_partner_ids:
account.update({
'final_debit': account['fin_bal']['debit'],
'final_credit': account['fin_bal']['credit'],
'final_balance': account['fin_bal']['balance'],
})
if foreign_currency:
account.update({
'final_bal_curr': account['fin_bal']['bal_curr'],
})
self.write_ending_balance_from_dict(account)
# 2 lines break
self.row_pos += 2
def write_initial_balance(self, my_object):
def write_initial_balance_from_dict(self, my_object):
"""Specific function to write initial balance for General Ledger"""
if 'partner' in my_object._name:
if 'partner' in my_object['type']:
label = _('Partner Initial balance')
my_object.currency_id = my_object.report_account_id.currency_id
elif 'account' in my_object._name:
elif 'account' in my_object['type']:
label = _('Initial balance')
super(GeneralLedgerXslx, self).write_initial_balance(
super(GeneralLedgerXslx, self).write_initial_balance_from_dict(
my_object, label
)
def write_ending_balance(self, my_object):
def write_ending_balance_from_dict(self, my_object):
"""Specific function to write ending balance for General Ledger"""
if 'partner' in my_object._name:
name = my_object.name
if 'partner' in my_object['type']:
name = my_object['name']
label = _('Partner ending balance')
elif 'account' in my_object._name:
name = my_object.code + ' - ' + my_object.name
elif 'account' in my_object['type']:
name = my_object['code'] + ' - ' + my_object['name']
label = _('Ending balance')
super(GeneralLedgerXslx, self).write_ending_balance(
super(GeneralLedgerXslx, self).write_ending_balance_from_dict(
my_object, name, label
)

1167
account_financial_report/report/journal_ledger.py
File diff suppressed because it is too large
View File

112
account_financial_report/report/journal_ledger_xlsx.py

@ -10,9 +10,15 @@ class JournalLedgerXslx(models.AbstractModel):
_name = 'report.a_f_r.report_journal_ledger_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
def _get_report_name(self, report):
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('Journal Ledger')
return self._get_report_complete_name(report, report_name)
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
columns = [
@ -36,7 +42,7 @@ class JournalLedgerXslx(models.AbstractModel):
if report.with_account_name:
columns.append({
'header': _('Account Name'),
'field': 'account',
'field': 'account_name',
'width': 15
})
@ -74,9 +80,9 @@ class JournalLedgerXslx(models.AbstractModel):
columns += [
{
'header': _('Currency'),
'field': 'currency_id',
'type': 'many2one',
'width': 14
'field': 'currency_name',
'width': 14,
'type': 'currency_name',
},
{
'header': _('Amount Currency'),
@ -181,51 +187,61 @@ class JournalLedgerXslx(models.AbstractModel):
_('Journals'),
', '.join([
"%s - %s" % (report_journal.code, report_journal.name)
for report_journal in report.report_journal_ledger_ids
for report_journal in report.journal_ids
])
]
]
def _generate_report_content(self, workbook, report):
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.journal_ledger'
]._get_report_values(report, data)
group_option = report.group_option
if group_option == 'journal':
for report_journal in report.report_journal_ledger_ids:
self._generate_journal_content(workbook, report_journal)
for ledger in res_data['Journal_Ledgers']:
self._generate_journal_content(workbook, report, res_data,
ledger)
elif group_option == 'none':
self._generate_no_group_content(workbook, report)
self._generate_no_group_content(workbook, report,
res_data)
def _generate_no_group_content(self, workbook, report):
def _generate_no_group_content(self, workbook, report, res_data):
self._generate_moves_content(
workbook, report, "Report", report.report_move_ids)
self._generate_no_group_taxes_summary(workbook, report)
workbook, "Report", report, res_data, res_data['Moves'])
self._generate_no_group_taxes_summary(workbook, report, res_data)
def _generate_journal_content(self, workbook, report_journal):
def _generate_journal_content(self, workbook, report, res_data, ledger):
journal = self.env['account.journal'].browse(ledger['id'])
currency_name = journal.currency_id and journal.currency_id.name or \
journal.company_id.currency_id.name
sheet_name = "%s (%s) - %s" % (
report_journal.code,
report_journal.currency_id.name,
report_journal.name,
journal.code,
currency_name,
journal.name,
)
self._generate_moves_content(
workbook, report_journal.report_id, sheet_name,
report_journal.report_move_ids)
self._generate_journal_taxes_summary(workbook, report_journal)
workbook, sheet_name, report, res_data, ledger['report_moves'])
self._generate_journal_taxes_summary(workbook, ledger)
def _generate_no_group_taxes_summary(self, workbook, report):
def _generate_no_group_taxes_summary(self, workbook, report, res_data):
self._generate_taxes_summary(
workbook, report, "Tax Report", report.report_tax_line_ids)
workbook, "Tax Report", res_data['tax_line_data'])
def _generate_journal_taxes_summary(self, workbook, report_journal):
def _generate_journal_taxes_summary(self, workbook, ledger):
journal = self.env['account.journal'].browse(ledger['id'])
currency_name = journal.currency_id and journal.currency_id.name or \
journal.company_id.currency_id.name
sheet_name = "Tax - %s (%s) - %s" % (
report_journal.code,
report_journal.currency_id.name,
report_journal.name,
journal.code,
currency_name,
journal.name,
)
report = report_journal.report_id
self._generate_taxes_summary(
workbook, report, sheet_name, report_journal.report_tax_line_ids)
workbook, sheet_name, ledger['tax_lines'])
def _generate_moves_content(self, workbook, report, sheet_name, moves):
def _generate_moves_content(self, workbook, sheet_name, report, res_data,
moves):
self.workbook = workbook
self.sheet = workbook.add_worksheet(sheet_name)
self._set_column_width()
@ -236,15 +252,45 @@ class JournalLedgerXslx(models.AbstractModel):
self.row_pos += 2
self.write_array_header()
account_ids_data = res_data['account_ids_data']
partner_ids_data = res_data['partner_ids_data']
currency_ids_data = res_data['currency_ids_data']
move_ids_data = res_data['move_ids_data']
for move in moves:
for line in move.report_move_line_ids:
self.write_line(line)
for line in move['report_move_lines']:
currency_data = currency_ids_data.get(
line['currency_id'], False)
currency_name = currency_data and currency_data['name'] or ''
account_data = account_ids_data.get(line['account_id'], False)
account_name = account_data and account_data['name'] or ''
account_code = account_data and account_data['code'] or ''
move_data = move_ids_data.get(line['move_id'], False)
move_entry = move_data and move_data['entry'] or ''
line['partner'] = self._get_partner_name(line['partner_id'],
partner_ids_data)
line['account_code'] = account_code
line['account_name'] = account_name
line['currency_name'] = currency_name
line['entry'] = move_entry
line['taxes_description'] = \
report._get_ml_tax_description(
line, res_data['tax_line_data'].get(
line['tax_line_id']),
res_data['move_line_ids_taxes_data'].get(
line['move_line_id'], False))
self.write_line_from_dict(line)
self.row_pos += 1
def _generate_taxes_summary(self, workbook, report, sheet_name, tax_lines):
def _generate_taxes_summary(self, workbook, sheet_name, tax_lines_dict):
self.workbook = workbook
self.sheet = workbook.add_worksheet(sheet_name)
self.row_pos = 1
self.write_array_title(sheet_name)
self.row_pos += 2
def _get_partner_name(self, partner_id, partner_data):
if partner_id in partner_data.keys():
return partner_data[partner_id]['name']
else:
return ''

1208
account_financial_report/report/open_items.py
File diff suppressed because it is too large
View File

121
account_financial_report/report/open_items_xlsx.py

@ -9,44 +9,51 @@ class OpenItemsXslx(models.AbstractModel):
_name = 'report.a_f_r.report_open_items_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
def _get_report_name(self, report):
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('Open Items')
return self._get_report_complete_name(report, report_name)
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
res = {
0: {'header': _('Date'), 'field': 'date', 'width': 11},
1: {'header': _('Entry'), 'field': 'entry', 'width': 18},
1: {'header': _('Entry'), 'field': 'move_id_name', 'width': 18},
2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
3: {'header': _('Account'), 'field': 'account', 'width': 9},
4: {'header': _('Partner'), 'field': 'partner', 'width': 25},
5: {'header': _('Ref - Label'), 'field': 'label', 'width': 40},
6: {'header': _('Due date'), 'field': 'date_due', 'width': 11},
5: {'header': _('Ref - Label'), 'field': 'ref', 'width': 40},
6: {'header': _('Due date'), 'field': 'date_maturity', 'width': 11},
7: {'header': _('Original'),
'field': 'amount_total_due',
'field': 'original',
'type': 'amount',
'width': 14},
8: {'header': _('Residual'),
'field': 'amount_residual',
'field_final_balance': 'final_amount_residual',
'field_final_balance': 'residual',
'type': 'amount',
'width': 14},
}
if report.foreign_currency:
foreign_currency = {
9: {'header': _('Cur.'), 'field': 'currency_id',
'field_currency_balance': 'currency_id',
'type': 'many2one', 'width': 7},
9: {'header': _('Cur.'), 'field': 'currency_name',
'field_currency_balance': 'currency_name',
'type': 'currency_name',
'width': 7},
10: {'header': _('Cur. Original'),
'field': 'amount_total_due_currency',
'field': 'amount_currency',
'field_final_balance':
'final_amount_total_due_currency',
'amount_currency',
'type': 'amount_currency',
'width': 14},
11: {'header': _('Cur. Residual'),
'field': 'amount_residual_currency',
'field_final_balance':
'final_amount_residual_currency',
'amount_currency',
'type': 'amount_currency',
'width': 14},
}
@ -55,9 +62,9 @@ class OpenItemsXslx(models.AbstractModel):
def _get_report_filters(self, report):
return [
[_('Date at filter'), report.date_at],
[_('Date at filter'), report.date_at.strftime("%d/%m/%Y")],
[_('Target moves filter'),
_('All posted entries') if report.only_posted_moves else _(
_('All posted entries') if report.target_move == 'posted' else _(
'All entries')],
[_('Account balance at 0 filter'),
_('Hide') if report.hide_account_at_0 else _('Show')],
@ -77,43 +84,65 @@ class OpenItemsXslx(models.AbstractModel):
def _get_col_pos_final_balance_label(self):
return 5
def _generate_report_content(self, workbook, report):
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.open_items']._get_report_values(
report, data)
# For each account
for account in report.account_ids:
Open_items = res_data['Open_Items']
accounts_data = res_data['accounts_data']
partners_data = res_data['partners_data']
total_amount = res_data['total_amount']
for account_id in Open_items.keys():
# Write account title
self.write_array_title(account.code + ' - ' + account.name)
self.write_array_title(accounts_data[account_id]['code'] + ' - ' +
accounts_data[account_id]['name'])
# For each partner
for partner in account.partner_ids:
# Write partner title
self.write_array_title(partner.name)
# Display array header for move lines
self.write_array_header()
# Display account move lines
for line in partner.move_line_ids:
self.write_line(line)
# Display ending balance line for partner
self.write_ending_balance(partner, 'partner')
# Line break
self.row_pos += 1
# Display ending balance line for account
self.write_ending_balance(account, 'account')
# 2 lines break
self.row_pos += 2
def write_ending_balance(self, my_object, type_object):
if Open_items[account_id]:
for partner_id in Open_items[account_id]:
type_object = 'partner'
# Write partner title
self.write_array_title(partners_data[partner_id]['name'])
# Display array header for move lines
self.write_array_header()
# Display account move lines
for line in Open_items[account_id][partner_id]:
self.write_line_from_dict(line)
# Display ending balance line for partner
self.write_ending_balance_from_dict(
partners_data[partner_id], type_object, total_amount,
account_id, partner_id)
# Line break
self.row_pos += 1
# Display ending balance line for account
type_object = 'account'
self.write_ending_balance_from_dict(accounts_data[account_id],
type_object,
total_amount,
account_id)
# 2 lines break
self.row_pos += 2
def write_ending_balance_from_dict(self, my_object, type_object,
total_amount, account_id=False,
partner_id=False):
"""Specific function to write ending balance for Open Items"""
if type_object == 'partner':
name = my_object.name
name = my_object['name']
my_object['residual'] = total_amount[account_id][partner_id][
'residual']
label = _('Partner ending balance')
my_object.currency_id = my_object.report_account_id.currency_id
elif type_object == 'account':
name = my_object.code + ' - ' + my_object.name
name = my_object['code'] + ' - ' + my_object['name']
my_object['residual'] = total_amount[account_id][
'residual']
label = _('Ending balance')
super(OpenItemsXslx, self).write_ending_balance(my_object, name, label)
super(OpenItemsXslx, self).write_ending_balance_from_dict(
my_object, name, label)

438
account_financial_report/report/templates/aged_partner_balance.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_aged_partner_balance_qweb">
<template id="aged_partner_balance">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
@ -13,10 +13,9 @@
<template id="report_aged_partner_balance_base">
<!-- Saved flag fields into variables, used to define columns display -->
<t t-set="show_move_line_details" t-value="o.show_move_line_details"/>
<t t-set="show_move_line_details" t-value="show_move_line_details"/>
<!-- Defines global variables used by internal layout -->
<t t-set="title">Aged Partner Balance - <t t-raw="o.company_id.name"/> - <t t-raw="o.company_id.currency_id.name"/></t>
<t t-set="company_name" t-value="o.company_id.name"/>
<t t-set="title">Aged Partner Balance - <t t-raw="company_name"/> - <t t-raw="currency_name"/></t>
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
@ -24,15 +23,15 @@
<!-- Display filters -->
<t t-call="account_financial_report.report_aged_partner_balance_filters"/>
<t t-foreach="o.account_ids" t-as="account">
<t t-foreach="aged_partner_balance" t-as="account">
<div class="page_break">
<!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title"
style="width: 100%;">
<span t-field="account.code"/>
<span t-esc="account['code']"/>
-
<span t-field="account.name"/>
<span t-esc="account['name']"/>
</div>
<!-- Display account lines -->
@ -42,8 +41,7 @@
<!-- Display account header -->
<t t-call="account_financial_report.report_aged_partner_balance_lines_header"/>
<t t-foreach="account.partner_ids" t-as="partner">
<t t-foreach="account['partners']" t-as="partner">
<!-- Display one line per partner -->
<t t-call="account_financial_report.report_aged_partner_balance_lines"/>
</t>
@ -57,11 +55,11 @@
<t t-if="show_move_line_details">
<!-- Display account partners -->
<t t-foreach="account.partner_ids" t-as="partner">
<t t-foreach="account['partners']" t-as="partner">
<div class="page_break">
<!-- Display partner header -->
<div class="act_as_caption account_title">
<span t-field="partner.name"/>
<span t-esc="partner['name']"/>
</div>
<!-- Display partner move lines -->
@ -69,7 +67,7 @@
<!-- Display partner footer -->
<t t-call="account_financial_report.report_aged_partner_balance_partner_ending_cumul">
<t t-set="partner_cumul_line" t-value="partner.line_ids"/>
<t t-set="partner_cumul_line" t-value="partner"/>
</t>
</div>
</t>
@ -90,11 +88,11 @@
</div>
<div class="act_as_row">
<div class="act_as_cell">
<span t-field="o.date_at"/>
<span t-esc="date_at"/>
</div>
<div class="act_as_cell">
<t t-if="o.only_posted_moves">All posted entries</t>
<t t-if="not o.only_posted_moves">All entries</t>
<t t-if="only_posted_moves">All posted entries</t>
<t t-if="not only_posted_moves">All entries</t>
</div>
</div>
</div>
@ -125,44 +123,41 @@
</template>
<template id="report_aged_partner_balance_lines">
<!-- Display each lines -->
<t t-foreach="partner.line_ids" t-as="line">
<!-- # lines -->
<div class="act_as_row lines">
<!--## partner-->
<div class="act_as_cell left">
<span t-field="line.partner"/>
</div>
<!--## amount_residual-->
<div class="act_as_cell amount">
<span t-field="line.amount_residual" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## current-->
<div class="act_as_cell amount">
<span t-field="line.current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_30_days-->
<div class="act_as_cell amount">
<span t-field="line.age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_60_days-->
<div class="act_as_cell amount">
<span t-field="line.age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_90_days-->
<div class="act_as_cell amount">
<span t-field="line.age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_120_days-->
<div class="act_as_cell amount">
<span t-field="line.age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## older-->
<div class="act_as_cell amount">
<span t-field="line.older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!-- Display each partner lines -->
<div class="act_as_row lines">
<!--## partner-->
<div class="act_as_cell left">
<span t-esc="partner['name']"/>
</div>
</t>
<!--## amount_residual-->
<div class="act_as_cell amount">
<span t-esc="partner['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## current-->
<div class="act_as_cell amount">
<span t-esc="partner['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_30_days-->
<div class="act_as_cell amount">
<span t-esc="partner['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_60_days-->
<div class="act_as_cell amount">
<span t-esc="partner['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_90_days-->
<div class="act_as_cell amount">
<span t-esc="partner['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_120_days-->
<div class="act_as_cell amount">
<span t-esc="partner['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## older-->
<div class="act_as_cell amount">
<span t-esc="partner['older']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
</div>
</template>
<template id="report_aged_partner_balance_move_lines">
@ -210,180 +205,194 @@
</div>
</div>
<!-- Display each move lines -->
<t t-foreach="partner.move_line_ids" t-as="line">
<t t-foreach="partner['move_lines']" t-as="line">
<!-- # lines or centralized lines -->
<div class="act_as_row lines">
<!--## date-->
<div class="act_as_cell left">
<span>
<a t-att-data-active-id="line.move_line_id.id"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action"
style="color: black;">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.id"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line.date" t-options="{'widget': 'date'}"/></a>
</span>
<t t-esc="line['date']" t-options="{'widget': 'date'}"/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## move-->
<div class="act_as_cell left">
<span>
<a t-att-data-active-id="line.move_line_id.move_id.id"
t-att-data-res-model="'account.move'"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.entry"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.move_id.id"-->
<!-- t-att-data-res-model="'account.move'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['entry']"/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## journal-->
<div class="act_as_cell left">
<span>
<a t-att-data-active-id="line.move_line_id.move_id.journal_id.id"
t-att-data-res-model="'account.journal'"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.journal"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.move_id.journal_id.id"-->
<!-- t-att-data-res-model="'account.journal'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['journal']"/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## account code-->
<div class="act_as_cell left">
<span>
<a t-att-data-active-id="line.move_line_id.account_id.id"
t-att-data-res-model="'account.account'"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.account"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.account_id.id"-->
<!-- t-att-data-res-model="'account.account'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['account']"/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## partner-->
<div class="act_as_cell left">
<span>
<a t-att-data-active-id="line.move_line_id.partner_id.id"
t-att-data-res-model="'res.partner'"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.partner"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.partner_id.id"-->
<!-- t-att-data-res-model="'res.partner'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['partner']"/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## ref - label-->
<div class="act_as_cell left">
<span>
<a t-att-data-active-id="line.move_line_id.id"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.label"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.id"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['ref']"/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## date_due-->
<div class="act_as_cell left">
<span>
<a t-att-data-active-id="line.move_line_id.id"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action"
style="color: black;">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.id"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line.date_due" t-options="{'widget': 'date'}"/></a>
</span>
<t t-esc="line['due_date']" t-options="{'widget': 'date'}"/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## amount_residual-->
<div class="act_as_cell amount">
<span>
<a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
style="color: black;">
<t t-raw="line.amount_residual" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## current-->
<div class="act_as_cell amount">
<t t-if="line.current != 0">
<span>
<a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
style="color: black;">
<t t-raw="line.current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="line.current == 0">
<span t-field="line.current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</t>
<!-- <t t-if="line.current != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.current == 0">-->
<!-- <span t-field="line.current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## age_30_days-->
<div class="act_as_cell amount">
<t t-if="line.age_30_days != 0">
<span>
<a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
style="color: black;">
<t t-raw="line.age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="line.age_30_days == 0">
<span t-field="line.age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</t>
<!-- <t t-if="line.age_30_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_30_days == 0">-->
<!-- <span t-field="line.age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## age_60_days-->
<div class="act_as_cell amount">
<t t-if="line.age_60_days != 0">
<span>
<a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
style="color: black;">
<t t-raw="line.age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="line.age_60_days == 0">
<span t-field="line.age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</t>
<!-- <t t-if="line.age_60_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_60_days == 0">-->
<!-- <span t-field="line.age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## age_90_days-->
<div class="act_as_cell amount">
<t t-if="line.age_90_days != 0">
<span>
<a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
style="color: black;">
<t t-raw="line.age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="line.age_90_days == 0">
<span t-field="line.age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</t>
<!-- <t t-if="line.age_90_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_90_days == 0">-->
<!-- <span t-field="line.age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## age_120_days-->
<div class="act_as_cell amount">
<t t-if="line.age_120_days != 0">
<span>
<a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
style="color: black;">
<t t-raw="line.age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="line.age_120_days == 0">
<span t-field="line.age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</t>
<!-- <t t-if="line.age_120_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_120_days == 0">-->
<!-- <span t-field="line.age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## older-->
<div class="act_as_cell amount">
<t t-if="line.older != 0">
<span>
<a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_multi"
style="color: black;">
<t t-raw="line.older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="line.older == 0">
<span t-field="line.older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</t>
<!-- <t t-if="line.older != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['older']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.older == 0">-->
<!-- <span t-field="line.older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
</div>
</t>
@ -401,31 +410,31 @@
<div class="act_as_cell" style="width: 6.00%;"/>
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-field="partner_cumul_line.amount_residual" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="partner_cumul_line['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## current-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-field="partner_cumul_line.current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="partner_cumul_line['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-field="partner_cumul_line.age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="partner_cumul_line['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-field="partner_cumul_line.age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="partner_cumul_line['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-field="partner_cumul_line.age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="partner_cumul_line['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-field="partner_cumul_line.age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="partner_cumul_line['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-field="partner_cumul_line.older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="partner_cumul_line['older']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
</div>
</div>
@ -440,31 +449,31 @@
<div class="act_as_cell right" style="width: 32.52%;">Total</div>
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-field="account.cumul_amount_residual" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## current-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-field="account.cumul_current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-field="account.cumul_age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-field="account.cumul_age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-field="account.cumul_age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-field="account.cumul_age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-field="account.cumul_older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['older']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
</t>
<t t-if="show_move_line_details">
@ -474,31 +483,31 @@
<div class="act_as_cell" style="width: 6.00%;"/>
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-field="account.cumul_amount_residual" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## current-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-field="account.cumul_current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-field="account.cumul_age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-field="account.cumul_age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-field="account.cumul_age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-field="account.cumul_age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-field="account.cumul_older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account['older']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
</t>
</div>
@ -510,23 +519,22 @@
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 9.64%;"/>
<!--## current-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-field="account.percent_current"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_current']"/>%
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-field="account.percent_age_30_days"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_30_days']"/>%
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-field="account.percent_age_60_days"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_60_days']"/>%
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-field="account.percent_age_90_days"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_90_days']"/>%
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-field="account.percent_age_120_days"/>
%
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_120_days']"/>%
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-field="account.percent_older"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_older']"/>%
</div>
</t>
<t t-if="show_move_line_details">
@ -538,22 +546,22 @@
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%"/>
<!--## current-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-field="account.percent_current"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_current']"/>%
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-field="account.percent_age_30_days"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_30_days']"/>%
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-field="account.percent_age_60_days"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_60_days']"/>%
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-field="account.percent_age_90_days"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_90_days']"/>%
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-field="account.percent_age_120_days"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_120_days']"/>%
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-field="account.percent_older"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_older']"/>%
</div>
</t>
</div>

347
account_financial_report/report/templates/general_ledger.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_general_ledger_qweb">
<template id="general_ledger">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
@ -13,28 +13,26 @@
<template id="report_general_ledger_base">
<!-- Saved flag fields into variables, used to define columns display -->
<t t-set="show_analytic_tags" t-value="o.show_analytic_tags"/>
<t t-set="show_cost_center" t-value="o.show_cost_center"/>
<t t-set="foreign_currency" t-value="o.foreign_currency"/>
<t t-set="foreign_currency" t-value="foreign_currency"/>
<!-- Defines global variables used by internal layout -->
<t t-set="title">General Ledger - <t t-raw="o.company_id.name"/> - <t t-raw="o.company_id.currency_id.name"/></t>
<t t-set="company_name" t-value="o.company_id.name"/>
<t t-set="title">General Ledger - <t t-raw="company_name"/> - <t t-raw="currency_name"/></t>
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
</div>
<!-- Display filters -->
<t t-call="account_financial_report.report_general_ledger_filters"/>
<t t-foreach="o.account_ids" t-as="account">
<t t-foreach="general_ledger" t-as="account">
<div class="page_break">
<!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title"
style="width: 100%">
<span t-field="account.code"/> - <span t-field="account.name"/>
<span t-esc="o._get_atr_from_dict(account['id'], accounts_data, 'code')"/> -
<span t-esc="o._get_atr_from_dict(account['id'], accounts_data, 'name')"/>
</div>
<t t-if="not account.partner_ids">
<t t-if="not account['partners']">
<!-- Display account move lines without partner regroup -->
<t t-set="type" t-value='"account_type"'/>
<t t-call="account_financial_report.report_general_ledger_lines">
@ -42,32 +40,35 @@
</t>
</t>
<t t-if="account.partner_ids">
<t t-if="account['partners']">
<!-- Display account partners -->
<t t-foreach="account.partner_ids" t-as="partner">
<t t-set="type" t-value='"partner_type"'/>
<div class="page_break">
<!-- Display partner header -->
<div class="act_as_caption account_title">
<span t-field="partner.name"/>
</div>
<t t-if="not centralize">
<t t-foreach="account['list_partner']" t-as="partner">
<t t-set="type" t-value='"partner_type"'/>
<div class="page_break">
<!-- Display partner header -->
<div class="act_as_caption account_title">
<span
t-esc="o._get_atr_from_dict(partner['id'], partners_data, 'name')"/>
</div>
<!-- Display partner move lines -->
<t t-call="account_financial_report.report_general_ledger_lines">
<t t-set="account_or_partner_object" t-value="partner"/>
</t>
<!-- Display partner move lines -->
<t t-call="account_financial_report.report_general_ledger_lines">
<t t-set="account_or_partner_object" t-value="partner"/>
</t>
<!-- Display partner footer -->
<t t-call="account_financial_report.report_general_ledger_ending_cumul">
<t t-set="account_or_partner_object" t-value="partner"/>
<t t-set="type" t-value='"partner_type"'/>
</t>
</div>
<!-- Display partner footer -->
<t t-call="account_financial_report.report_general_ledger_ending_cumul">
<t t-set="account_or_partner_object" t-value="partner"/>
<t t-set="type" t-value='"partner_type"'/>
</t>
</div>
</t>
</t>
</t>
<!-- Display account footer -->
<t t-if="not o.filter_partner_ids" t-call="account_financial_report.report_general_ledger_ending_cumul">
<t t-if="not account['partners']" t-call="account_financial_report.report_general_ledger_ending_cumul">
<t t-set="account_or_partner_object" t-value="account"/>
<t t-set="type" t-value='"account_type"'/>
</t>
@ -87,23 +88,23 @@
</div>
<div class="act_as_row">
<div class="act_as_cell">
From: <span t-field="o.date_from"/> To: <span t-field="o.date_to"/>
From: <span t-esc="date_from"/> To: <span t-esc="date_to"/>
</div>
<div class="act_as_cell">
<t t-if="o.only_posted_moves">All posted entries</t>
<t t-if="not o.only_posted_moves">All entries</t>
<t t-if="only_posted_moves">All posted entries</t>
<t t-if="not only_posted_moves">All entries</t>
</div>
<div class="act_as_cell">
<t t-if="o.hide_account_at_0">Hide</t>
<t t-if="not o.hide_account_at_0">Show</t>
<t t-if="hide_account_at_0">Hide</t>
<t t-if="not hide_account_at_0">Show</t>
</div>
<div class="act_as_cell">
<t t-if="o.centralize">Yes</t>
<t t-if="not o.centralize">No</t>
<t t-if="centralize">Yes</t>
<t t-if="not centralize">No</t>
</div>
<div class="act_as_cell">
<t t-if="o.show_analytic_tags">Yes</t>
<t t-if="not o.show_analytic_tags">No</t>
<t t-if="show_analytic_tags">Yes</t>
<t t-if="not show_analytic_tags">No</t>
</div>
</div>
</div>
@ -188,29 +189,29 @@
<div class="act_as_cell amount">
<t t-if="type == 'account_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.account_id.id),
('date', '&lt;', o.date_from.strftime('%Y-%m-%d')),
t-value="[('account_id', '=', account['id']),
('date', '&lt;', date_from),
('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_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.initial_debit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
<t t-raw="account_or_partner_object['init_bal']['debit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="type == 'partner_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.report_account_id.account_id.id),
('partner_id', '=', account_or_partner_object.partner_id.id),
('date', '&lt;', o.date_from.strftime('%Y-%m-%d')),
t-value="[('account_id', '=', account['id']),
('partner_id', '=', partner['id']),
('date', '&lt;', date_from),
('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_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.initial_debit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
<t t-raw="account_or_partner_object['init_bal']['debit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</div>
@ -218,29 +219,31 @@
<div class="act_as_cell amount">
<t t-if="type == 'account_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.account_id.id),
('date', '&lt;', o.date_from.strftime('%Y-%m-%d')),
t-value="[('account_id', '=', account['id']),
('date', '&lt;', date_from),
('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_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.initial_credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
<t
t-raw="account_or_partner_object['init_bal']['credit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="type == 'partner_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.report_account_id.account_id.id),
('partner_id', '=', account_or_partner_object.partner_id.id),
('date', '&lt;', o.date_from.strftime('%Y-%m-%d')),
t-value="[('account_id', '=', account['id']),
('partner_id', '=', partner['id']),
('date', '&lt;', date_from),
('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_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.initial_credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
<t
t-raw="account_or_partner_object['init_bal']['credit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</div>
@ -248,64 +251,66 @@
<div class="act_as_cell amount">
<t t-if="type == 'account_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.account_id.id),
('date', '&lt;', o.date_from.strftime('%Y-%m-%d'))]"/>
t-value="[('account_id', '=', account['id']),
('date', '&lt;', date_from)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.initial_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
<t
t-raw="account_or_partner_object['init_bal']['balance']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="type == 'partner_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.report_account_id.account_id.id),
('partner_id', '=', account_or_partner_object.partner_id.id),
('date', '&lt;', o.date_from.strftime('%Y-%m-%d'))]"/>
t-value="[('account_id', '=', account['id']),
('partner_id', '=', partner['id']),
('date', '&lt;', date_from)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.initial_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
<t t-raw="account_or_partner_object['init_bal']['balance']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</div>
<t t-if="foreign_currency">
<t t-if="account.account_id.currency_id.id">
<t t-if="o._get_atr_from_dict(account['id'], accounts_data, 'currency_id')">
<div class="act_as_cell amount" style="width: 2.08%;">
<span t-field="account.account_id.currency_id.display_name"/>
<span t-field="o._get_atr_from_dict(account['id'], accounts_data, 'currency_name')"/>
</div>
<div class="act_as_cell amount" style="width: 5.19%;">
<t t-if="type == 'account_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.account_id.id),
t-value="[('account_id', '=', account['id']),
('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_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.initial_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': account.account_id.currency_id}"/></a>
<t
t-raw="account_or_partner_object['init_bal']['bal_curr']" t-options="{'widget': 'monetary', 'display_currency': account.account_id.currency_id}"/></a>
</span>
</t>
<t t-if="type == 'partner_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.report_account_id.account_id.id),
('partner_id', '=', account_or_partner_object.partner_id.id),
t-value="[('account_id', '=', account['id']),
('partner_id', '=', partner['id']),
('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_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.initial_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': account.account_id.currency_id}"/></a>
<t t-raw="account_or_partner_object['init_bal']['bal_curr']" t-options="{'widget': 'monetary', 'display_currency': account.account_id.currency_id}"/></a>
</span>
</t>
</div>
</t>
<t t-if="not account.account_id.currency_id.id">
<t t-if="not o._get_atr_from_dict(account['id'], accounts_data, 'currency_id')">
<div class="act_as_cell" style="width: 2.08%;"/>
<div class="act_as_cell" style="width: 5.19%;"/>
</t>
@ -313,76 +318,102 @@
</div>
<!-- Display each lines -->
<t t-foreach="account_or_partner_object.move_line_ids" t-as="line">
<t t-foreach="account_or_partner_object['move_lines']" t-as="line">
<!-- # lines or centralized lines -->
<div class="act_as_row lines">
<!--## date-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move.line'"/>
<span>
<a t-att-data-active-id="line.move_line_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line.date" t-options="{'widget': 'date'}"/></a>
<t t-if="line['id']">
<a t-att-data-active-id="line['id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line['date']" t-options="{'widget': 'date'}"/></a>
</t>
<t t-if="not line['id']">
<a class="o_account_financial_reports_web_action"
style="color: black;">
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line['date']" t-options="{'widget': 'date'}"/></a>
</t>
</span>
</div>
<!--## move-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move'"/>
<span>
<a t-att-data-active-id="line.move_line_id.move_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.entry"/></a>
</span>
<t t-if="line['entry_id']">
<span>
<a t-att-data-active-id="line['entry_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line['entry']"/></a>
</span>
</t>
</div>
<!--## journal-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'account.journal'"/>
<span>
<a t-att-data-active-id="line.move_line_id.move_id.journal_id.id"
<a t-att-data-active-id="line['journal_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.journal"/></a>
<t t-raw="o._get_atr_from_dict(line['journal_id'], journals_data, 'code')"/></a>
</span>
</div>
<!--## account code-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'account.account'"/>
<span>
<a t-att-data-active-id="line.move_line_id.account_id.id"
<a t-att-data-active-id="account['id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.account"/></a>
<t t-raw="o._get_atr_from_dict(account['id'], accounts_data, 'code')"/></a>
</span>
</div>
<!--## taxes-->
<div class="act_as_cell left"><span t-field="line.taxes_description"/></div>
<div class="act_as_cell left">
<t t-if="taxes_data and line['tax_ids']">
<t t-foreach="line['tax_ids']" t-as="tax_id">
<span t-esc="o._get_atr_from_dict(tax_id, taxes_data, 'amount')"/> <span t-esc="o._get_atr_from_dict(tax_id, taxes_data, 'string')"/>
</t>
</t>
</div>
<!--## partner-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'res.partner'"/>
<span t-if="line.partner">
<a t-att-data-active-id="line.move_line_id.partner_id.id"
<span t-if="line['partner_id']">
<a t-att-data-active-id="line['partner_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;"><t t-raw="line.partner"/></a>
style="color: black;"><t
t-raw="line['partner_name']"/></a>
</span>
</div>
<!--## ref - label-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move.line'"/>
<span>
<a t-att-data-active-id="line.move_line_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.label"/></a>
</span>
<t t-if="line['id']">
<span>
<a t-att-data-active-id="line['id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line['ref']"/></a>
</span>
</t>
<t t-if="not line['id']">
<span>
<a class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line['ref']"/></a>
</span>
</t>
</div>
<!--## cost_center-->
<t t-if="show_cost_center">
@ -398,71 +429,105 @@
</t>
<t t-if="show_analytic_tags">
<!--## analytic tags-->
<div class="act_as_cell left"><span t-field="line.tags"/></div>
<div class="act_as_cell left">
<t t-if="line['tag_ids']">
<t t-foreach="line['tag_ids']" t-as="tag_id">
<span t-esc="o._get_atr_from_dict(tag_id, tags_data, 'name')"/>
</t>
</t>
</div>
</t>
<!--## matching_number-->
<div class="act_as_cell">
<t t-set="res_model" t-value="'account.full.reconcile'"/>
<span t-if="line.matching_number">
<a t-att-data-active-id="line.move_line_id.full_reconcile_id.id"
<span t-if="line['rec_id']">
<a t-att-data-active-id="line['rec_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;"><t t-raw="line.matching_number"/></a>
style="color: black;"><t t-raw="line['rec_name']"/></a>
</span>
</div>
<!--## debit-->
<div class="act_as_cell amount">
<t t-set="res_model" t-value="'account.move.line'"/>
<span>
<a t-att-data-active-id="line.move_line_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line.debit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
<t t-if="line['id']">
<span>
<a t-att-data-active-id="line['id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line['debit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="not line['id']">
<span>
<a class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line['debit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</div>
<!--## credit-->
<div class="act_as_cell amount">
<t t-set="res_model" t-value="'account.move.line'"/>
<span>
<a t-att-data-active-id="line.move_line_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line.credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
<t t-if="line['id']">
<span>
<a t-att-data-active-id="line['id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line['credit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="not line['id']">
<span>
<a class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line['credit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</div>
<!--## balance cumulated-->
<div class="act_as_cell amount">
<t t-set="res_model" t-value="'account.move.line'"/>
<span>
<a t-att-data-active-id="line.move_line_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line.cumul_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
<t t-if="line['id']">
<span>
<a t-att-data-active-id="line['id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line['balance']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
<t t-if="not line['id']">
<span>
<a class="o_account_financial_reports_web_action_monetary"
style="color: black;">
<t t-raw="line['balance']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
</t>
</div>
<t t-if="foreign_currency">
<t t-if="line.currency_id.id">
<t t-if="line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell amount" style="width: 2.08%;">
<span t-field="line.currency_id.display_name"/>
<span t-esc="line['currency_id'][1]"/>
</div>
<!--## amount_currency-->
<div class="act_as_cell amount" style="width: 5.19%;">
<t t-set="res_model" t-value="'account.move.line'"/>
<span>
<a t-att-data-active-id="line.move_line_id.id"
<a t-att-data-active-id="line['id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.amount_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/></a>
<t t-raw="line['bal_curr']"/></a>
</span>
</div>
</t>
<t t-if="not line.currency_id.id">
<t t-if="not line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell amount" style="width: 2.08%;"/>
<!--## amount_currency-->
@ -482,7 +547,7 @@
<t t-if='type == "account_type"'>
<div class="act_as_cell first_column"
style="width: 41.32%;"><span
t-field="account_or_partner_object.code"/> - <span t-field="account_or_partner_object.name"/></div>
t-esc="o._get_atr_from_dict(account['id'], accounts_data, 'code')"/> - <span t-esc="o._get_atr_from_dict(account['id'], accounts_data, 'name')"/></div>
<div class="act_as_cell right"
style="width: 22.9%;">Ending balance</div>
</t>
@ -502,51 +567,53 @@
<div class="act_as_cell" style="width: 2.41%;"/>
<!--## debit-->
<div class="act_as_cell amount" style="width: 6.02%;">
<span t-field="account_or_partner_object.final_debit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account_or_partner_object['fin_bal']['debit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## credit-->
<div class="act_as_cell amount" style="width: 6.02%;">
<span t-field="account_or_partner_object.final_credit" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account_or_partner_object['fin_bal']['credit']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## balance cumulated-->
<div class="act_as_cell amount" style="width: 6.02%;">
<span t-field="account_or_partner_object.final_balance" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="account_or_partner_object['fin_bal']['balance']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## currency_name + amount_currency-->
<t t-if="foreign_currency">
<t t-if="account.account_id.currency_id.id">
<t t-if="o._get_atr_from_dict(account['id'], accounts_data, 'currency_id')">
<div class="act_as_cell amount" style="width: 2.08%;">
<span t-field="account.account_id.currency_id.display_name"/>
<span t-field="o._get_atr_from_dict(account['id'], accounts_data, 'currency_name')"/>
</div>
<div class="act_as_cell amount" style="width: 5.19%;">
<t t-if="type == 'account_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.account_id.id),
('date', '&lt;', o.date_from)]"/>
t-value="[('account_id', '=', account['id']),
('date', '&lt;', date_from)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.final_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': account_or_partner_object.account_id.currency_id}"/></a>
<t
t-raw="account_or_partner_object['fin_bal']['bal_curr']" t-options="{'widget': 'monetary', 'display_currency': account_or_partner_object.account_id.currency_id}"/></a>
</span>
</t>
<t t-if="type == 'partner_type'">
<t t-set="domain"
t-value="[('account_id', '=', account_or_partner_object.report_account_id.account_id.id),
('partner_id', '=', account_or_partner_object.partner_id.id),
('date', '&lt;', o.date_from)]"/>
<t t-set="domain" t-value="[('account_id', '=', account['id']),
('partner_id', '=', partner['id']),
('date', '&lt;', date_from)]"/>
<span>
<a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;">
<t t-raw="account_or_partner_object.final_balance_foreign_currency" t-options="{'widget': 'monetary', 'display_currency': account_or_partner_object.report_account_id.currency_id}"/></a>
<t t-raw="account_or_partner_object['fin_bal']['bal_curr']" t-options="{'widget': 'monetary', 'display_currency': account_or_partner_object.report_account_id.currency_id}"/></a>
</span>
</t>
</div>
</t>
<t t-if="not account.account_id.currency_id ">
<t t-if="not o._get_atr_from_dict(account['id'], accounts_data, 'currency_id')">
<div class="act_as_cell amount" style="width: 2.08%;"/>
<div class="act_as_cell amount" style="width: 5.19%;"/>
</t>

110
account_financial_report/report/templates/journal_ledger.xml

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright 2018 Eficent Business and IT Consulting Services S.L.
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<template id="report_journal_ledger_qweb">
<template id="journal_ledger">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
@ -12,23 +15,23 @@
</template>
<template id="report_journal_ledger_base">
<t t-set="display_currency" t-value="o.foreign_currency"/>
<t t-set="display_account_name" t-value="o.with_account_name"/>
<t t-set="title">Journal Ledger - <t t-raw="o.company_id.name"/> - <t t-raw="o.company_id.currency_id.name"/></t>
<t t-set="company_name" t-value="o.company_id.name"/>
<t t-set="display_currency" t-value="foreign_currency"/>
<t t-set="display_account_name" t-value="with_account_name"/>
<t t-set="title">Journal Ledger - <t t-raw="company_name"/> - <t t-raw="currency_name"/></t>
<t t-set="company_name" t-value="Company_Name"/>
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
</div>
<t t-if="o.group_option == 'none'">
<t t-if="group_option == 'none'">
<div class="page_break">
<t t-call="account_financial_report.report_journal_all"/>
<br/>
<t t-call="account_financial_report.report_journal_all_taxes"/>
</div>
</t>
<t t-if="o.group_option == 'journal'">
<t t-foreach="o.report_journal_ledger_ids" t-as="journal">
<t t-if="group_option == 'journal'">
<t t-foreach="Journal_Ledgers" t-as="journal">
<div class="page_break">
<t t-call="account_financial_report.report_journal_ledger_journal"/>
<br/>
@ -44,7 +47,7 @@
<div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_table data_table" style="width: 100%;">
<t t-call="account_financial_report.report_journal_ledger_journal_table_header"/>
<t t-foreach="o.report_move_ids" t-as="move">
<t t-foreach="Moves" t-as="move">
<t t-call="account_financial_report.report_journal_move"/>
</t>
</div>
@ -53,13 +56,13 @@
<template id="account_financial_report.report_journal_ledger_journal">
<div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title" style="width: 100%;">
<span t-field="journal.name"/> (<span t-field="journal.currency_id.display_name"/>) - <span t-field="o.date_from"/> to <span t-field="o.date_to"/> - <span t-field="o.move_target"/> Moves
<span t-esc="journal['name']"/> (<span t-esc="journal['currency_name']"/>) - <span t-esc="date_from" t-options="{'widget': 'date'}"/> to <span t-esc="date_to" t-options="{'widget': 'date'}"/> - <span t-esc="move_target"/> Moves
</div>
<div class="act_as_table data_table" style="width: 100%;">
<t t-call="account_financial_report.report_journal_ledger_journal_table_header"/>
<t t-call="account_financial_report.report_journal_ledger_journal_first_line"/>
<t t-foreach="journal.report_move_ids" t-as="move">
<t t-foreach="journal['report_moves']" t-as="move">
<t t-call="account_financial_report.report_journal_move"/>
</t>
</div>
@ -155,11 +158,11 @@
name="taxes"/>
<div class="act_as_cell amount"
name="debit">
<b><span t-field="journal.debit"/></b>
<b><span t-esc="journal['debit']" t-options="{'widget': 'float', 'precision': 2}"/></b>
</div>
<div class="act_as_cell amount"
name="credit">
<b><span t-field="journal.credit"/></b>
<b><span t-esc="journal['credit']" t-options="{'widget': 'float', 'precision': 2}"/></b>
</div>
<t t-if="display_currency">
<div class="act_as_cell"
@ -177,9 +180,9 @@
<t t-set="display_move_info" t-value="True"/>
<t t-set="last_partner" t-eval="None"/>
<t t-set="display_partner" t-eval="True"/>
<t t-foreach="move.report_move_line_ids" t-as="move_line">
<t t-foreach="move['report_move_lines']" t-as="move_line">
<div class="act_as_row lines">
<t t-set="current_partner" t-value="move_line.partner_id"/>
<t t-set="current_partner" t-value="o._get_partner_name(move_line['partner_id'], partner_ids_data)"/>
<t t-set="display_partner" t-value="current_partner != last_partner"/>
<t t-call="account_financial_report.report_journal_move_line"/>
<t t-set="last_partner" t-value="current_partner"/>
@ -191,54 +194,65 @@
<template id="account_financial_report.report_journal_move_line">
<div class="act_as_cell left"
name="entry">
<span t-if="display_move_info" t-field="move_line.entry"/>
<t t-set="res_model" t-value="'account.move'"/>
<span t-if="display_move_info">
<a t-att-data-active-id="move_line['move_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-esc="o._get_atr_from_dict(move_line['move_id'], move_ids_data, 'entry')"/>
</a>
</span>
</div>
<div class="act_as_cell left"
name="date">
<span t-if="display_move_info" t-field="move_line.date"/>
<span t-if="display_move_info" t-esc="move_line['date']" t-options="{'widget': 'date'}"/>
</div>
<div class="act_as_cell left"
name="account">
<span t-field="move_line.account_code"/>
<span t-esc="o._get_atr_from_dict(move_line['account_id'], account_ids_data, 'code')"/>
<span t-if="display_account_name">
- <span t-field="move_line.account"/>
- <span t-esc="o._get_atr_from_dict(move_line['account_id'], account_ids_data, 'name')"/>
</span>
</div>
<div class="act_as_cell left"
name="partner">
<span t-if="display_partner" t-field="move_line.partner"/>
<span t-if="display_partner" t-esc="o._get_partner_name(move_line['partner_id'], partner_ids_data)"/>
</div>
<div class="act_as_cell left"
name="label">
<span t-field="move_line.label"/>
<span t-if="move_line['label']" t-esc="move_line['label']"/>
<span t-if="not move_line['label']">/</span>
</div>
<div class="act_as_cell left"
name="taxes">
<span t-field="move_line.taxes_description"/>
<t t-set="tax_line_dat" t-value="o._get_data_from_dict(move_line['tax_line_id'], tax_line_data)"/>
<t t-set="move_line_ids_taxes_dat" t-value="o._get_data_from_dict(move_line['move_line_id'], move_line_ids_taxes_data)"/>
<span t-esc="o._get_ml_tax_description(move_line, tax_line_dat, move_line_ids_taxes_dat)"/>
</div>
<div class="act_as_cell amount"
name="debit">
<t t-if="move_line.debit">
<span t-field="move_line.debit"/>
<t t-if="move_line['debit']">
<span t-esc="move_line['debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</t>
</div>
<div class="act_as_cell amount"
name="credit">
<t t-if="move_line.credit">
<span t-field="move_line.credit"/>
<t t-if="move_line['credit']">
<span t-esc="move_line['credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</t>
</div>
<t t-if="display_currency">
<div class="act_as_cell"
name="currency_name">
<t t-if="move_line.currency_name">
<span t-field="move_line.currency_name"/>
<t t-if="move_line['currency_id']">
<span t-esc="currency_ids_data.get(move_line['currency_id'], '')"/>
</t>
</div>
<div class="act_as_cell amount"
name="amount_currency">
<t t-if="move_line.amount_currency">
<span t-field="move_line.amount_currency"/>
<t t-if="move_line['amount_currency']" t-options="{'widget': 'float', 'precision': 2}">
<span t-esc="move_line['amount_currency']" t-options="{'widget': 'float', 'precision': 2}"/>
</t>
</div>
</t>
@ -314,39 +328,39 @@
</div>
</div>
<t t-foreach="journal.report_tax_line_ids" t-as="tax_line">
<t t-foreach="journal['tax_lines']" t-as="tax_line">
<div class="act_as_row lines">
<div class="act_as_cell left"
name="tax_name">
<span t-field="tax_line.tax_name"/>
<span t-esc="tax_line['tax_name']"/>
</div>
<div class="act_as_cell left"
name="tax_code">
<span t-field="tax_line.tax_code"/>
<span t-esc="tax_line['tax_code']"/>
</div>
<div class="act_as_cell amount"
name="base_debit">
<span t-field="tax_line.base_debit"/>
<span t-esc="tax_line['base_debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="base_credit">
<span t-field="tax_line.base_credit"/>
<span t-esc="tax_line['base_credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="base_balance">
<span t-field="tax_line.base_balance"/>
<span t-esc="tax_line['base_balance']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_debit">
<span t-field="tax_line.tax_debit"/>
<span t-esc="tax_line['tax_debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_credit">
<span t-field="tax_line.tax_credit"/>
<span t-esc="tax_line['tax_credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_balance">
<span t-field="tax_line.tax_balance"/>
<span t-esc="tax_line['tax_balance']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
</div>
</t>
@ -423,39 +437,39 @@
</div>
</div>
<t t-foreach="o.report_tax_line_ids" t-as="tax_line">
<t t-foreach="ReportTaxLines" t-as="tax_line">
<div class="act_as_row lines">
<div class="act_as_cell left"
name="tax_name">
<span t-field="tax_line.tax_name"/>
<span t-esc="tax_line['tax_name']"/>
</div>
<div class="act_as_cell left"
name="tax_code">
<span t-field="tax_line.tax_code"/>
<span t-esc="tax_line['tax_code']"/>
</div>
<div class="act_as_cell amount"
name="base_debit">
<span t-field="tax_line.base_debit"/>
<span t-esc="tax_line['base_debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="base_credit">
<span t-field="tax_line.base_credit"/>
<span t-esc="tax_line['base_credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="base_balance">
<span t-field="tax_line.base_balance"/>
<span t-esc="tax_line['base_balance']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_debit">
<span t-field="tax_line.tax_debit"/>
<span t-esc="tax_line['tax_debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_credit">
<span t-field="tax_line.tax_credit"/>
<span t-esc="tax_line['tax_credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_balance">
<span t-field="tax_line.tax_balance"/>
<span t-esc="tax_line['tax_balance']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
</div>
</t>

106
account_financial_report/report/templates/open_items.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="account_financial_report.report_open_items_qweb">
<template id="open_items">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
@ -13,10 +13,10 @@
<template id="account_financial_report.report_open_items_base">
<!-- Saved flag fields into variables, used to define columns display -->
<t t-set="foreign_currency" t-value="o.foreign_currency"/>
<t t-set="foreign_currency" t-value="foreign_currency"/>
<!-- Defines global variables used by internal layout -->
<t t-set="title">Open Items - <t t-raw="o.company_id.name"/> - <t t-raw="o.company_id.currency_id.name"/></t>
<t t-set="company_name" t-value="o.company_id.name"/>
<t t-set="title">Open Items - <t t-raw="company_name"/> - <t t-raw="currency_name"/></t>
<t t-set="company_name" t-value="Company_Name"/>
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
@ -24,23 +24,23 @@
<!-- Display filters -->
<t t-call="account_financial_report.report_open_items_filters"/>
<t t-foreach="o.account_ids" t-as="account">
<t t-foreach="Open_Items.keys()" t-as="account_id">
<div class="page_break">
<!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;" />
<div class="account_title"
style="width: 100%;">
<span t-field="account.code"/>
<span t-esc="accounts_data[account_id]['code']"/>
-
<span t-field="account.name"/>
<span t-esc="accounts_data[account_id]['name']"/>
</div>
<!-- Display account partners -->
<t t-foreach="account.partner_ids" t-as="partner">
<t t-foreach="Open_Items[account_id]" t-as="partner_id" >
<div class="page_break">
<!-- Display partner header -->
<div class="account_title">
<span t-field="partner.name"/>
<div class="act_as_caption account_title">
<span t-esc="partners_data[partner_id]['name']"/>
</div>
<!-- Display partner move lines -->
@ -48,7 +48,8 @@
<!-- Display partner footer -->
<t t-call="account_financial_report.report_open_items_ending_cumul">
<t t-set="account_or_partner_object" t-value="partner"/>
<t t-set="account_or_partner_id" t-value="partners_data[partner_id]"/>
<t t-set="currency_id" t-value="accounts_data[account_id]['currency_name']"/>
<t t-set="type" t-value='"partner_type"'/>
</t>
</div>
@ -56,7 +57,8 @@
<!-- Display account footer -->
<t t-call="account_financial_report.report_open_items_ending_cumul">
<t t-set="account_or_partner_object" t-value="account"/>
<t t-set="account_or_partner_id" t-value="accounts_data[account_id]"/>
<t t-set="currency_id" t-value="accounts_data[account_id]['currency_name']"/>
<t t-set="type" t-value='"account_type"'/>
</t>
</div>
@ -73,15 +75,15 @@
</div>
<div class="act_as_row">
<div class="act_as_cell">
<span t-field="o.date_at"/>
<span t-esc="date_at"/>
</div>
<div class="act_as_cell">
<t t-if="o.only_posted_moves">All posted entries</t>
<t t-if="not o.only_posted_moves">All entries</t>
<t t-if="target_move == 'posted'">All posted entries</t>
<t t-if="target_move == 'all'">All entries</t>
</div>
<div class="act_as_cell">
<t t-if="o.hide_account_at_0">Hide</t>
<t t-if="not o.hide_account_at_0">Show</t>
<t t-if="hide_account_at_0">Hide</t>
<t t-if="not hide_account_at_0">Show</t>
</div>
</div>
</div>
@ -127,78 +129,71 @@
</div>
<!-- Display each lines -->
<t t-foreach="partner.move_line_ids" t-as="line">
<t t-foreach="Open_Items[account_id][partner_id]" t-as="line" >
<!-- # lines or centralized lines -->
<div class="act_as_row lines">
<!--## date-->
<div class="act_as_cell left">
<span t-field="line.date"/>
<span t-raw="line['date']"/>
</div>
<!--## move-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move'"/>
<span>
<a t-att-data-active-id="line.move_line_id.move_id.id"
<a t-att-data-active-id="line['move_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.entry"/>
<t t-esc="line['move_name']"/>
</a>
</span>
</div>
<!--## journal-->
<div class="act_as_cell left">
<span t-field="line.journal"/>
<span t-esc="line['journal']"/>
</div>
<!--## account code-->
<div class="act_as_cell left">
<span t-field="line.account"/>
<span t-esc="line['account']"/>
</div>
<!--## partner-->
<div class="act_as_cell left">
<t t-set="res_model" t-value="'res.partner'"/>
<span t-if="line.partner">
<a t-att-data-active-id="line.move_line_id.partner_id.id"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-raw="line.partner"/>
</a>
</span>
<!-- <span t-if="line.get('partner_id', False)" t-esc="line['partner_id']"/>-->
<span t-esc="line['partner_name']"/>
</div>
<!--## ref - label-->
<div class="act_as_cell left">
<span t-field="line.label"/>
<span t-esc="line['ref']"/>
</div>
<!--## date_due-->
<div class="act_as_cell left">
<span t-field="line.date_due"/>
<span t-esc="line['date_maturity']"/>
</div>
<!--## amount_total_due-->
<div class="act_as_cell amount">
<span t-field="line.amount_total_due" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-if="line.get('original', False)" t-esc="line['original']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<!--## amount_residual-->
<div class="act_as_cell amount">
<span t-field="line.amount_residual" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span t-esc="line['amount_residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</div>
<t t-if="foreign_currency">
<t t-if="line.currency_id.id">
<t t-if="line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell amount">
<span t-field="line.currency_id.display_name"/>
<span t-esc="line['currency_name']"/>
</div>
<!--## amount_total_due_currency-->
<div class="act_as_cell amount">
<span t-field="line.amount_total_due_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/>
<span t-esc="line['amount_currency']"/>
</div>
<!--## amount_residual_currency-->
<div class="act_as_cell amount">
<span t-field="line.amount_residual_currency" t-options="{'widget': 'monetary', 'display_currency': line.currency_id}"/>
<span t-esc="line['amount_residual_currency']"/>
</div>
</t>
<t t-if="not line.currency_id.id">
<!--## currency_name-->
<t t-if="not line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell"/>
<!--## amount_total_due_currency-->
<div class="act_as_cell"/>
@ -218,9 +213,9 @@
<!--## date-->
<t t-if='type == "account_type"'>
<div class="act_as_cell first_column" style="width: 36.34%;">
<span t-field="account_or_partner_object.code"/>
<span t-esc="accounts_data[account_id]['code']"/>
-
<span t-field="account_or_partner_object.name"/>
<span t-esc="accounts_data[account_id]['name']"/>
</div>
<div class="act_as_cell right" style="width: 28.66%;">Ending
balance</div>
@ -237,32 +232,21 @@
<div class="act_as_cell amount" style="width: 6.57%;"/>
<!--## amount_currency-->
<div class="act_as_cell amount" style="width: 6.57%;">
<span t-field="account_or_partner_object.final_amount_residual" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<t t-if='type == "account_type"'>
<span t-esc="total_amount[account_id]['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</t>
<t t-if='type == "partner_type"'>
<span t-esc="total_amount[account_id][partner_id]['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
</t>
</div>
<!--## amount_total_due_currency + amount_residual_currency -->
<t t-if="foreign_currency">
<t t-if="account_or_partner_object.currency_id.id">
<!--## currency_name-->
<div class="act_as_cell amount" style="width: 2.25%;">
<span t-field="account_or_partner_object.currency_id.display_name"/>
</div>
<!--## amount_total_due_currency-->
<div class="act_as_cell amount" style="width: 6.57%;">
<span t-field="account_or_partner_object.final_amount_total_due_currency" t-options="{'widget': 'monetary', 'display_currency': account_or_partner_object.currency_id}"/>
</div>
<!--## amount_residual_currency-->
<div class="act_as_cell amount" style="width: 6.57%;">
<span t-field="account_or_partner_object.final_amount_residual_currency" t-options="{'widget': 'monetary', 'display_currency': account_or_partner_object.currency_id}"/>
</div>
</t>
<t t-if="not account_or_partner_object.currency_id.id">
<!--## currency_name-->
<div class="act_as_cell"/>
<!--## amount_total_due_currency-->
<div class="act_as_cell"/>
<!--## amount_residual_currency-->
<div class="act_as_cell"/>
</t>
</t>
</div>
</div>

1033
account_financial_report/report/templates/trial_balance.xml
File diff suppressed because it is too large
View File

172
account_financial_report/report/templates/vat_report.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="account_financial_report.report_vat_report_qweb">
<template id="vat_report">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
@ -12,8 +12,8 @@
</template>
<template id="account_financial_report.report_vat_report_base">
<t t-set="title">VAT Report - <t t-raw="o.company_id.name"/> - <t t-raw="o.company_id.currency_id.name"/></t>
<t t-set="company_name" t-value="o.company_id.name"/>
<t t-set="title">VAT Report - <t t-raw="company_name"/> - <t t-raw="currency_name"/></t>
<t t-set="company_name" t-value="company_name"/>
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
@ -36,105 +36,101 @@
</div>
</div>
<t t-foreach="o.taxtags_ids" t-as="tag">
<t t-foreach="vat_report" t-as="tag_or_group">
<div class="act_as_row lines" style="font-weight: bold;">
<t t-if="tag.taxtag_id">
<t t-set="res_model" t-value="'account.account.tag'"/>
<t t-set="res_id" t-value="tag.taxtag_id.id"/>
</t>
<t t-if="tag.taxgroup_id">
<t t-set="res_model" t-value="'account.tax.group'"/>
<t t-set="res_id" t-value="tag.taxgroup_id.id"/>
</t>
<div class="act_as_cell left oe_tooltip_string" style="width: 5%;">
<span>
<a t-att-data-active-id="res_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="tag.code"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-active-id="res_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="tag_or_group['code']"/>
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell left oe_tooltip_string" style="width: 65%;">
<span>
<a t-att-data-active-id="res_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="tag.name"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-active-id="res_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="tag_or_group['name']"/>
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell amount" style="width: 15%;">
<t t-set="domain"
t-value="[('tax_ids', 'in', [tax.tax_id.id for tax in tag.tax_ids]),
('date', '&gt;=', o.date_from),
('date', '&lt;=', o.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="tag.net"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_ids', 'in', [tax.tax_id.id for tax in tag.tax_ids]),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.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="tag_or_group['net']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell amount" style="width: 15%;">
<t t-set="domain"
t-value="[('tax_line_id', 'in', [tax.tax_id.id for tax in tag.tax_ids]),
('date', '&gt;=', o.date_from),
('date', '&lt;=', o.date_to),
('tax_exigible', '=', True)]"/>
<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="tag.tax"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_line_id', 'in', [tax.tax_id.id for tax in tag.tax_ids]),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <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="tag_or_group['tax']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
</div>
</div>
<t t-if="o.tax_detail">
<t t-foreach="tag.tax_ids" t-as="tax">
<t t-set="res_model" t-value="'account.tax'"/>
<t t-if="tax_detail">
<t t-foreach="tag_or_group['taxes']" t-as="tax">
<div class="act_as_row lines">
<div class="act_as_cell" style="width: 5%;"/>
<div class="act_as_cell left oe_tooltip_string" style="padding-left: 20px; width: 65%;">
<span>
<a t-att-data-active-id="tax.tax_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="tax.name"/></a>
</span>
<!-- <span>-->
<!-- <a t-att-data-active-id="tax.tax_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="tax['name']"/>
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell amount" style="width: 15%;">
<t t-set="domain"
t-value="[('tax_ids', 'in', tax.tax_id.ids),
('date', '&gt;=', o.date_from),
('date', '&lt;=', o.date_to),
('tax_exigible', '=', True)]"/>
<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="tax.net"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_ids', 'in', tax.tax_id.ids),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <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="tax['net']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell amount" style="width: 15%;">
<t t-set="domain"
t-value="[('tax_line_id', '=', tax.tax_id.id),
('date', '&gt;=', o.date_from),
('date', '&lt;=', o.date_to),
('tax_exigible', '=', True)]"/>
<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="tax.tax"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/></a>
</span>
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_line_id', '=', tax.tax_id.id),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <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="tax['tax']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
</div>
</div>
</t>
@ -153,13 +149,13 @@
</div>
<div class="act_as_row">
<div class="act_as_cell">
<span t-field="o.date_from"/>
<span t-esc="date_from"/>
</div>
<div class="act_as_cell">
<span t-field="o.date_to"/>
<span t-esc="date_to"/>
</div>
<div class="act_as_cell">
<span t-field="o.based_on"/>
<span t-esc="based_on"/>
</div>
</div>
</div>

1190
account_financial_report/report/trial_balance.py
File diff suppressed because it is too large
View File

110
account_financial_report/report/trial_balance_xlsx.py

@ -10,9 +10,15 @@ class TrialBalanceXslx(models.AbstractModel):
_name = 'report.a_f_r.report_trial_balance_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
def _get_report_name(self, report):
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('Trial Balance')
return self._get_report_complete_name(report, report_name)
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
if not report.show_partner_details:
@ -73,11 +79,11 @@ class TrialBalanceXslx(models.AbstractModel):
'type': 'amount',
'width': 14},
4: {'header': _('Period balance'),
'field': 'period_balance',
'field': 'balance',
'type': 'amount',
'width': 14},
5: {'header': _('Ending balance'),
'field': 'final_balance',
'field': 'ending_balance',
'type': 'amount',
'width': 14},
}
@ -88,11 +94,11 @@ class TrialBalanceXslx(models.AbstractModel):
'field_currency_balance': 'currency_id',
'type': 'many2one', 'width': 7},
7: {'header': _('Initial balance'),
'field': 'initial_balance_foreign_currency',
'field': 'initial_currency_balance',
'type': 'amount_currency',
'width': 14},
8: {'header': _('Ending balance'),
'field': 'final_balance_foreign_currency',
'field': 'ending_currency_balance',
'type': 'amount_currency',
'width': 14},
}
@ -104,7 +110,7 @@ class TrialBalanceXslx(models.AbstractModel):
[_('Date range filter'),
_('From: %s To: %s') % (report.date_from, report.date_to)],
[_('Target moves filter'),
_('All posted entries') if report.only_posted_moves else _(
_('All posted entries') if report.target_move == 'all' else _(
'All entries')],
[_('Account at 0 filter'),
_('Hide') if report.hide_account_at_0 else _('Show')],
@ -121,37 +127,87 @@ class TrialBalanceXslx(models.AbstractModel):
def _get_col_count_filter_value(self):
return 3
def _generate_report_content(self, workbook, report):
if not report.show_partner_details:
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.trial_balance']._get_report_values(
report, data)
trial_balance = res_data['trial_balance']
total_amount = res_data['total_amount']
partners_data = res_data['partners_data']
accounts_data = res_data['accounts_data']
hierarchy_on = res_data['hierarchy_on']
show_partner_details = res_data['show_partner_details']
show_hierarchy_level = res_data['show_hierarchy_level']
foreign_currency = res_data['foreign_currency']
limit_hierarchy_level = res_data['limit_hierarchy_level']
if not show_partner_details:
# Display array header for account lines
self.write_array_header()
# For each account
for account in report.account_ids.filtered(lambda a: not a.hide_line):
if not report.show_partner_details:
# Display account lines
self.write_line(account, 'account')
else:
if not show_partner_details:
for balance in trial_balance:
if hierarchy_on == 'relation':
if limit_hierarchy_level:
if show_hierarchy_level > balance['level']:
# Display account lines
self.write_line_from_dict(balance)
else:
self.write_line_from_dict(balance)
elif hierarchy_on == 'computed':
if balance['type'] == 'account_type':
if limit_hierarchy_level:
if show_hierarchy_level > balance['level']:
# Display account lines
self.write_line_from_dict(balance)
else:
self.write_line_from_dict(balance)
else:
self.write_line_from_dict(balance)
else:
for account_id in total_amount:
# Write account title
self.write_array_title(account.code + ' - ' + account.name)
self.write_array_title(accounts_data[account_id]['code'] + '- '
+ accounts_data[account_id]['name'])
# Display array header for partner lines
self.write_array_header()
# For each partner
for partner in account.partner_ids:
# Display partner lines
self.write_line(partner, 'partner')
for partner_id in total_amount[account_id]:
if isinstance(partner_id, int):
# Display partner lines
self.write_line_from_dict_order(
total_amount[account_id][partner_id],
partners_data[partner_id])
# Display account footer line
self.write_account_footer(account,
account.code + ' - ' + account.name)
accounts_data[account_id].update({
'initial_balance': total_amount[account_id][
'initial_balance'],
'credit': total_amount[account_id]['credit'],
'debit': total_amount[account_id]['debit'],
'balance': total_amount[account_id]['balance'],
'ending_balance': total_amount[account_id]['ending_balance']
})
if foreign_currency:
accounts_data[account_id].update({
'initial_currency_balance': total_amount[account_id][
'initial_currency_balance'],
'ending_currency_balance': total_amount[account_id][
'ending_currency_balance']
})
self.write_account_footer(accounts_data[account_id],
accounts_data[account_id][
'code'] + '- '
+ accounts_data[account_id]['name'])
# Line break
self.row_pos += 2
def write_line_from_dict_order(self, total_amount, partner_data):
total_amount.update({'name': str(partner_data['name'])})
self.write_line_from_dict(total_amount)
def write_line(self, line_object, type_object):
"""Write a line on current line using all defined columns field name.
Columns are defined with `_get_report_columns` method.
@ -164,12 +220,12 @@ class TrialBalanceXslx(models.AbstractModel):
def write_account_footer(self, account, name_value):
"""Specific function to write account footer for Trial Balance"""
format_amt = self._get_currency_amt_header_format(account)
format_amt = self._get_currency_amt_header_format_dict(account)
for col_pos, column in self.columns.items():
if column['field'] == 'name':
value = name_value
else:
value = getattr(account, column['field'])
value = account[column['field']]
cell_type = column.get('type', 'string')
if cell_type == 'string':
self.sheet.write_string(self.row_pos, col_pos, value or '',
@ -177,11 +233,11 @@ class TrialBalanceXslx(models.AbstractModel):
elif cell_type == 'amount':
self.sheet.write_number(self.row_pos, col_pos, float(value),
self.format_header_amount)
elif cell_type == 'many2one':
elif cell_type == 'many2one' and account['currency_id']:
self.sheet.write_string(
self.row_pos, col_pos, value.name or '',
self.format_header_right)
elif cell_type == 'amount_currency' and account.currency_id:
elif cell_type == 'amount_currency' and account['currency_id']:
self.sheet.write_number(
self.row_pos, col_pos, float(value),
format_amt)

525
account_financial_report/report/vat_report.py

@ -1,356 +1,189 @@
# Copyright 2018 Forest and Biomass Romania
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
from odoo import models, api
class VATReport(models.TransientModel):
_name = "report_vat_report"
_inherit = 'account_financial_report_abstract'
""" Here, we just define class fields.
For methods, go more bottom at this file.
class VATReport(models.AbstractModel):
_name = 'report.account_financial_report.vat_report'
The class hierarchy is :
* VATReport
** VATReportTaxTags
*** VATReportTax
"""
# Filters fields, used for data computation
company_id = fields.Many2one(comodel_name='res.company')
date_from = fields.Date()
date_to = fields.Date()
based_on = fields.Selection([('taxtags', 'Tax Tags'),
('taxgroups', 'Tax Groups')],
string='Based On',
required=True,
default='taxtags')
tax_detail = fields.Boolean('Tax Detail')
# Data fields, used to browse report data
taxtags_ids = fields.One2many(
comodel_name='report_vat_report_taxtag',
inverse_name='report_id'
)
class VATReportTaxTags(models.TransientModel):
_name = 'report_vat_report_taxtag'
_inherit = 'account_financial_report_abstract'
_order = 'code ASC'
report_id = fields.Many2one(
comodel_name='report_vat_report',
ondelete='cascade',
index=True
)
# Data fields, used to keep link with real object
taxtag_id = fields.Many2one(
'account.account.tag',
index=True
)
taxgroup_id = fields.Many2one(
'account.tax.group',
index=True
)
# Data fields, used for report display
code = fields.Char()
name = fields.Char()
net = fields.Float(digits=(16, 2))
tax = fields.Float(digits=(16, 2))
# Data fields, used to browse report data
tax_ids = fields.One2many(
comodel_name='report_vat_report_tax',
inverse_name='report_tax_id',
string='Taxes'
)
class VATReportTax(models.TransientModel):
_name = 'report_vat_report_tax'
_inherit = 'account_financial_report_abstract'
_order = 'name ASC'
report_tax_id = fields.Many2one(
comodel_name='report_vat_report_taxtag',
ondelete='cascade',
index=True
)
# Data fields, used to keep link with real object
tax_id = fields.Many2one(
'account.tax',
index=True,
string='Tax ID',
)
# Data fields, used for report display
code = fields.Char()
name = fields.Char()
net = fields.Float(digits=(16, 2))
tax = fields.Float(digits=(16, 2))
class VATReportCompute(models.TransientModel):
""" Here, we just define methods.
For class fields, go more top at this file.
"""
_inherit = 'report_vat_report'
@api.multi
def print_report(self, report_type='qweb'):
self.ensure_one()
if report_type == 'xlsx':
report_name = 'a_f_r.report_vat_report_xlsx'
else:
report_name = 'account_financial_report.report_vat_report_qweb'
context = dict(self.env.context)
action = self.env['ir.actions.report'].search(
[('report_name', '=', report_name),
('report_type', '=', report_type)], limit=1)
return action.with_context(context).report_action(self, config=False)
def _get_html(self):
result = {}
rcontext = {}
context = dict(self.env.context)
report = self.browse(context.get('active_id'))
if report:
rcontext['o'] = report
result['html'] = self.env.ref(
'account_financial_report.report_vat_report').render(
rcontext)
return result
def _get_tax_data(self, tax_ids):
taxes = self.env['account.tax'].browse(tax_ids)
tax_data = {}
for tax in taxes:
tax_data.update({
tax.id: {
'id': tax.id,
'name': tax.name,
'tax_group_id': tax.tax_group_id.id,
'tags_ids': tax.tag_ids.ids
}
})
return tax_data
@api.model
def get_html(self, given_context=None):
return self.with_context(given_context)._get_html()
@api.multi
def compute_data_for_report(self):
self.ensure_one()
# Compute report data
if self.based_on == 'taxtags':
self._inject_taxtags_values()
self._inject_tax_taxtags_values()
elif self.based_on == 'taxgroups':
self._inject_taxgroups_values()
self._inject_tax_taxgroups_values()
# Refresh cache because all data are computed with SQL requests
self.refresh()
def _inject_taxtags_values(self):
"""Inject report values for report_vat_report_taxtags."""
query_inject_taxtags = """
WITH
taxtags AS
(SELECT coalesce(regexp_replace(tag.name,
'[^0-9\\.]+', '', 'g'), ' ') AS code,
tag.name, tag.id,
coalesce(sum(movetax.tax_base_amount), 0.00) AS net,
coalesce(sum(movetax.balance), 0.00) AS tax
FROM
account_account_tag AS tag
INNER JOIN account_tax_account_tag AS taxtag
ON tag.id = taxtag.account_account_tag_id
INNER JOIN account_tax AS tax
ON tax.id = taxtag.account_tax_id
INNER JOIN account_move_line AS movetax
ON movetax.tax_line_id = tax.id
INNER JOIN account_move AS move
ON move.id = movetax.move_id
WHERE tag.id is not null AND movetax.tax_exigible
AND move.company_id = %s AND move.date >= %s
AND move.date <= %s AND move.state = 'posted'
GROUP BY tag.id
ORDER BY code, tag.name
def _get_vat_report_domain(self, company_id, date_from, date_to):
domain = [('company_id', '=', company_id),
('date', '>=', date_from),
('date', '<', date_to),
('tax_line_id', '!=', False),
('tax_exigible', '=', True)]
return domain
def _get_vat_report_data(self, company_id, date_from, date_to):
domain = self._get_vat_report_domain(company_id, date_from, date_to)
ml_fields = ['id', 'tax_base_amount', 'balance', 'tax_line_id',
'analytic_tag_ids']
tax_move_lines = self.env['account.move.line'].search_read(
domain=domain,
fields=ml_fields,
)
INSERT INTO
report_vat_report_taxtag
(
report_id,
create_uid,
create_date,
taxtag_id,
code,
name,
net, tax
)
SELECT
%s AS report_id,
%s AS create_uid,
NOW() AS create_date,
tag.id,
tag.code,
tag.name,
abs(tag.net),
abs(tag.tax)
FROM
taxtags tag
"""
query_inject_taxtags_params = (self.company_id.id, self.date_from,
self.date_to, self.id, self.env.uid)
self.env.cr.execute(query_inject_taxtags, query_inject_taxtags_params)
vat_data = {}
tax_ids = set()
for tax_move_line in tax_move_lines:
tax_ml_id = tax_move_line['id']
vat_data[tax_ml_id] = {}
vat_data[tax_ml_id].update({
'id': tax_ml_id,
'net': tax_move_line['tax_base_amount'],
'tax': tax_move_line['balance'] if tax_move_line[
'balance'] > 0 else (-1) * tax_move_line['balance'],
'tax_line_id': tax_move_line['tax_line_id'],
})
tax_ids.add(tax_move_line['tax_line_id'][0])
tax_data = self._get_tax_data(tax_ids)
return vat_data, tax_data
def _get_tax_group_data(self, tax_group_ids):
tax_groups = self.env['account.tax.group'].browse(tax_group_ids)
tax_group_data = {}
for tax_group in tax_groups:
tax_group_data.update({
tax_group.id: {
'id': tax_group.id,
'name': tax_group.name,
'code': str(tax_group.sequence),
}
})
return tax_group_data
def _get_vat_report_group_data(self, vat_report_data, tax_data, tax_detail):
vat_report = {}
for tax_move_line in vat_report_data.values():
tax_id = tax_move_line['tax_line_id'][0]
tax_group_id = tax_data[tax_id]['tax_group_id']
if tax_group_id not in vat_report.keys():
vat_report[tax_group_id] = {}
vat_report[tax_group_id]['net'] = 0.0
vat_report[tax_group_id]['tax'] = 0.0
vat_report[tax_group_id][tax_id] = tax_data[tax_id]
vat_report[tax_group_id][tax_id].update(
{'net': 0.0, 'tax': 0.0}
)
else:
if tax_id not in vat_report[tax_group_id].keys():
vat_report[tax_group_id][tax_id] = tax_data[tax_id]
vat_report[tax_group_id][tax_id].update(
{'net': 0.0, 'tax': 0.0}
)
vat_report[tax_group_id]['net'] += tax_move_line['net']
vat_report[tax_group_id]['tax'] += tax_move_line['tax']
vat_report[tax_group_id][tax_id]['net'] += tax_move_line['net']
vat_report[tax_group_id][tax_id]['tax'] += tax_move_line['tax']
tax_group_data = self._get_tax_group_data(vat_report.keys())
vat_report_list = []
for tax_group_id in vat_report.keys():
vat_report[tax_group_id]['name'] = tax_group_data[
tax_group_id]['name']
vat_report[tax_group_id]['code'] = tax_group_data[
tax_group_id]['code']
if tax_detail:
vat_report[tax_group_id]['taxes'] = []
for tax_id in vat_report[tax_group_id]:
if isinstance(tax_id, int):
vat_report[tax_group_id]['taxes'].append(
vat_report[tax_group_id][tax_id]
)
vat_report_list.append(vat_report[tax_group_id])
return vat_report_list
def _get_tags_data(self, tags_ids):
tags = self.env['account.account.tag'].browse(tags_ids)
tags_data = {}
for tag in tags:
tags_data.update({tag.id: {
'code': "",
'name': tag.name}
})
return tags_data
def _get_vat_report_tag_data(self, vat_report_data, tax_data, tax_detail):
vat_report = {}
for tax_move_line in vat_report_data.values():
tax_id = tax_move_line['tax_line_id'][0]
tags_ids = tax_data[tax_id]['tags_ids']
if tags_ids:
for tag_id in tags_ids:
if tag_id not in vat_report.keys():
vat_report[tag_id] = {}
vat_report[tag_id]['net'] = 0.0
vat_report[tag_id]['tax'] = 0.0
vat_report[tag_id][tax_id] = tax_data[tax_id]
vat_report[tag_id][tax_id].update(
{'net': 0.0, 'tax': 0.0}
)
else:
if tax_id not in vat_report[tag_id].keys():
vat_report[tag_id][tax_id] = tax_data[tax_id]
vat_report[tag_id][tax_id].update(
{'net': 0.0, 'tax': 0.0}
)
vat_report[tag_id][tax_id]['net'] += tax_move_line['net']
vat_report[tag_id][tax_id]['tax'] += tax_move_line['tax']
vat_report[tag_id]['net'] += tax_move_line['net']
vat_report[tag_id]['tax'] += tax_move_line['tax']
tags_data = self._get_tags_data(vat_report.keys())
vat_report_list = []
for tag_id in vat_report.keys():
vat_report[tag_id]['name'] = tags_data[tag_id]['name']
vat_report[tag_id]['code'] = tags_data[tag_id]['code']
if tax_detail:
vat_report[tag_id]['taxes'] = []
for tax_id in vat_report[tag_id]:
if isinstance(tax_id, int):
vat_report[tag_id]['taxes'].append(
vat_report[tag_id][tax_id]
)
vat_report_list.append(vat_report[tag_id])
return vat_report_list
def _inject_taxgroups_values(self):
"""Inject report values for report_vat_report_taxtags."""
query_inject_taxgroups = """
WITH
taxgroups AS
(SELECT coalesce(taxgroup.sequence, 0) AS code,
taxgroup.name, taxgroup.id,
coalesce(sum(movetax.tax_base_amount), 0.00) AS net,
coalesce(sum(movetax.balance), 0.00) AS tax
FROM
account_tax_group AS taxgroup
INNER JOIN account_tax AS tax
ON tax.tax_group_id = taxgroup.id
INNER JOIN account_move_line AS movetax
ON movetax.tax_line_id = tax.id
INNER JOIN account_move AS move
ON move.id = movetax.move_id
WHERE taxgroup.id is not null AND movetax.tax_exigible
AND move.company_id = %s AND move.date >= %s
AND move.date <= %s AND move.state = 'posted'
GROUP BY taxgroup.id
ORDER BY code, taxgroup.name
)
INSERT INTO
report_vat_report_taxtag
(
report_id,
create_uid,
create_date,
taxgroup_id,
code,
name,
net, tax
)
SELECT
%s AS report_id,
%s AS create_uid,
NOW() AS create_date,
groups.id,
groups.code,
groups.name,
abs(groups.net),
abs(groups.tax)
FROM
taxgroups groups
"""
query_inject_taxgroups_params = (self.company_id.id, self.date_from,
self.date_to, self.id, self.env.uid)
self.env.cr.execute(query_inject_taxgroups,
query_inject_taxgroups_params)
def _inject_tax_taxtags_values(self):
""" Inject report values for report_vat_report_tax. """
# pylint: disable=sql-injection
query_inject_tax = """
WITH
taxtags_tax AS
(
SELECT
tag.id AS report_tax_id, ' ' AS code,
tax.name, tax.id,
coalesce(sum(movetax.tax_base_amount), 0.00) AS net,
coalesce(sum(movetax.balance), 0.00) AS tax
FROM
report_vat_report_taxtag AS tag
INNER JOIN account_tax_account_tag AS taxtag
ON tag.taxtag_id = taxtag.account_account_tag_id
INNER JOIN account_tax AS tax
ON tax.id = taxtag.account_tax_id
INNER JOIN account_move_line AS movetax
ON movetax.tax_line_id = tax.id
INNER JOIN account_move AS move
ON move.id = movetax.move_id
WHERE tag.id is not null AND movetax.tax_exigible
AND tag.report_id = %s AND move.company_id = %s
AND move.date >= %s AND move.date <= %s
AND move.state = 'posted'
GROUP BY tag.id, tax.id
ORDER BY tax.name
)
INSERT INTO
report_vat_report_tax
(
report_tax_id,
create_uid,
create_date,
tax_id,
name,
net,
tax
)
SELECT
tt.report_tax_id,
%s AS create_uid,
NOW() AS create_date,
tt.id,
tt.name,
abs(tt.net),
abs(tt.tax)
FROM
taxtags_tax tt
"""
query_inject_tax_params = (self.id, self.company_id.id, self.date_from,
self.date_to, self.env.uid)
self.env.cr.execute(query_inject_tax, query_inject_tax_params)
def _inject_tax_taxgroups_values(self):
""" Inject report values for report_vat_report_tax. """
# pylint: disable=sql-injection
query_inject_tax = """
WITH
taxtags_tax AS
(
SELECT
taxtag.id AS report_tax_id, ' ' AS code,
tax.name, tax.id,
coalesce(sum(movetax.tax_base_amount), 0.00) AS net,
coalesce(sum(movetax.balance), 0.00) AS tax
FROM
report_vat_report_taxtag AS taxtag
INNER JOIN account_tax AS tax
ON tax.tax_group_id = taxtag.taxgroup_id
INNER JOIN account_move_line AS movetax
ON movetax.tax_line_id = tax.id
INNER JOIN account_move AS move
ON move.id = movetax.move_id
WHERE taxtag.id is not null AND movetax.tax_exigible
AND taxtag.report_id = %s AND move.company_id = %s
AND move.date >= %s AND move.date <= %s
AND move.state = 'posted'
GROUP BY taxtag.id, tax.id
ORDER BY tax.name
)
INSERT INTO
report_vat_report_tax
(
report_tax_id,
create_uid,
create_date,
tax_id,
name,
net,
tax
)
SELECT
tt.report_tax_id,
%s AS create_uid,
NOW() AS create_date,
tt.id,
tt.name,
abs(tt.net),
abs(tt.tax)
FROM
taxtags_tax tt
"""
query_inject_tax_params = (self.id, self.company_id.id, self.date_from,
self.date_to, self.env.uid)
self.env.cr.execute(query_inject_tax, query_inject_tax_params)
@api.multi
def _get_report_values(self, docids, data):
wizard_id = data['wizard_id']
company = self.env['res.company'].browse(data['company_id'])
company_id = data['company_id']
date_from = data['date_from']
date_to = data['date_to']
based_on = data['based_on']
tax_detail = data['tax_detail']
vat_report_data, tax_data = self._get_vat_report_data(
company_id, date_from, date_to)
if based_on == 'taxgroups':
vat_report = self._get_vat_report_group_data(
vat_report_data, tax_data, tax_detail)
else:
vat_report = self._get_vat_report_tag_data(
vat_report_data, tax_data, tax_detail)
return {
'doc_ids': [wizard_id],
'doc_model': 'open.items.report.wizard',
'docs': self.env['open.items.report.wizard'].browse(wizard_id),
'company_name': company.display_name,
'currency_name': company.currency_id.name,
'date_to': data['date_to'],
'date_from': data['date_from'],
'based_on': data['based_on'],
'tax_detail': data['tax_detail'],
'vat_report': vat_report,
}

38
account_financial_report/report/vat_report_xlsx.py

@ -8,9 +8,15 @@ class VATReportXslx(models.AbstractModel):
_name = 'report.a_f_r.report_vat_report_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
def _get_report_name(self, report):
report_name = _('VAT Report')
return self._get_report_complete_name(report, report_name)
def _get_report_name(self, report, data):
company_id = data.get('company_id', False)
report_name = _('Vat Report')
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
return {
@ -28,9 +34,10 @@ class VATReportXslx(models.AbstractModel):
def _get_report_filters(self, report):
return [
[_('Date from'), report.date_from],
[_('Date to'), report.date_to],
[_('Based on'), report.based_on],
[_('Date from'), report.date_from.strftime("%d/%m/%Y")],
[_('Date to'), report.date_to.strftime("%d/%m/%Y")],
[_('Based on'), _('Tax Tags') if report.based_on == 'taxtags'else
_('Tax Groups')]
]
def _get_col_count_filter_name(self):
@ -39,14 +46,19 @@ class VATReportXslx(models.AbstractModel):
def _get_col_count_filter_value(self):
return 2
def _generate_report_content(self, workbook, report):
# For each taxtag
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.vat_report'
]._get_report_values(report, data)
vat_report = res_data['vat_report']
tax_detail = res_data['tax_detail']
# For each tax_tag tax_group
self.write_array_header()
for taxtag in report.taxtags_ids:
for tag_or_group in vat_report:
# Write taxtag line
self.write_line(taxtag)
self.write_line_from_dict(tag_or_group)
# For each tax if detail taxes
if report.tax_detail:
for tax in taxtag.tax_ids:
self.write_line(tax)
if tax_detail:
for tax in tag_or_group['taxes']:
self.write_line_from_dict(tax)

152
account_financial_report/reports.xml

@ -5,112 +5,122 @@
<!-- General Ledger -->
<report
id="action_report_general_ledger_qweb"
model="report_general_ledger"
id="action_print_report_general_ledger_qweb"
model="general.ledger.report.wizard"
string="General Ledger"
report_type="qweb-pdf"
name="account_financial_report.report_general_ledger_qweb"
file="account_financial_report.report_general_ledger_qweb"
menu="False"
name="account_financial_report.general_ledger"
file="account_financial_report.general_ledger"
/>
<report
id="action_report_general_ledger_html"
model="report_general_ledger"
id="action_print_report_general_ledger_html"
model="general.ledger.report.wizard"
string="General Ledger"
report_type="qweb-html"
name="account_financial_report.report_general_ledger_qweb"
file="account_financial_report.report_general_ledger_html"
menu="False"
name="account_financial_report.general_ledger"
file="account_financial_report.general_ledger"
/>
<!-- Journal Ledger -->
<report
id="action_report_journal_ledger_qweb"
model="report_journal_ledger"
string="Journal Ledger"
report_type="qweb-pdf"
name="account_financial_report.report_journal_ledger_qweb"
file="account_financial_report.report_journal_ledger_qweb"
/>
<report
id="action_report_journal_ledger_html"
model="report_journal_ledger"
string="Journal Ledger"
report_type="qweb-html"
name="account_financial_report.report_journal_ledger_qweb"
file="account_financial_report.report_journal_ledger_html"
/>
<report id="action_print_journal_ledger_wizard_qweb"
model="journal.ledger.report.wizard"
report_type="qweb-pdf"
menu="False"
string="Journal Ledger"
name="account_financial_report.journal_ledger"
file="account_financial_report.journal_ledger"
/>
<report id="action_print_journal_ledger_wizard_html"
model="journal.ledger.report.wizard"
report_type="qweb-html"
menu="False"
string="Journal Ledger"
name="account_financial_report.journal_ledger"
file="account_financial_report.journal_ledger"
/>
<!-- Trial Balance -->
<report
id="action_report_trial_balance_qweb"
model="report_trial_balance"
model="trial.balance.report.wizard"
string="Trial Balance"
menu="False"
report_type="qweb-pdf"
name="account_financial_report.report_trial_balance_qweb"
file="account_financial_report.report_trial_balance_qweb"
name="account_financial_report.trial_balance"
file="account_financial_report.trial_balance"
/>
<report
id="action_report_trial_balance_html"
model="report_trial_balance"
model="trial.balance.report.wizard"
string="Trial Balance"
menu="False"
report_type="qweb-html"
name="account_financial_report.report_trial_balance_qweb"
file="account_financial_report.report_trial_balance_html"
name="account_financial_report.trial_balance"
file="account_financial_report.trial_balance"
/>
<!-- Open Items -->
<report
id="action_report_open_items_qweb"
model="report_open_items"
id="action_print_report_open_items_qweb"
model="open.items.report.wizard"
string="Open Items"
menu="False"
report_type="qweb-pdf"
name="account_financial_report.report_open_items_qweb"
file="account_financial_report.report_open_items_qweb"
name="account_financial_report.open_items"
file="account_financial_report.open_items"
/>
<report
id="action_report_open_items_html"
model="report_open_items"
id="action_print_report_open_items_html"
model="open.items.report.wizard"
string="Open Items"
menu="False"
report_type="qweb-html"
name="account_financial_report.report_open_items_qweb"
file="account_financial_report.report_open_items_html"
name="account_financial_report.open_items"
file="account_financial_report.open_items"
/>
<!-- Aged Partner Balance -->
<report
id="action_report_aged_partner_balance_qweb"
model="report_aged_partner_balance"
id="action_print_report_aged_partner_balance_qweb"
model="aged.partner.balance.report.wizard"
string="Aged Partner Balance"
report_type="qweb-pdf"
name="account_financial_report.report_aged_partner_balance_qweb"
file="account_financial_report.report_aged_partner_balance_qweb"
menu="False"
name="account_financial_report.aged_partner_balance"
file="account_financial_report.aged_partner_balance"
/>
<report
id="action_report_aged_partner_balance_html"
model="report_aged_partner_balance"
id="action_print_report_aged_partner_balance_html"
model="aged.partner.balance.report.wizard"
string="Aged Partner Balance"
report_type="qweb-html"
name="account_financial_report.report_aged_partner_balance_qweb"
file="account_financial_report.report_aged_partner_balance_html"
menu="False"
name="account_financial_report.aged_partner_balance"
file="account_financial_report.aged_partner_balance"
/>
<!-- VAT Report -->
<report
id="action_report_vat_report_qweb"
model="report_vat_report"
id="action_print_report_vat_report_qweb"
model="vat.report.wizard"
string="VAT Report"
report_type="qweb-pdf"
name="account_financial_report.report_vat_report_qweb"
file="account_financial_report.report_vat_report_qweb"
menu="False"
name="account_financial_report.vat_report"
file="account_financial_report.vat_report"
/>
<report
id="action_report_vat_report_html"
model="report_vat_report"
id="action_print_report_vat_report_html"
model="vat.report.wizard"
string="VAT Report"
report_type="qweb-html"
name="account_financial_report.report_vat_report_qweb"
file="account_financial_report.report_vat_report_html"
menu="False"
name="account_financial_report.vat_report"
file="account_financial_report.vat_report"
/>
<!-- PDF REPORTS : paperformat -->
<record id="report_qweb_paperformat" model="report.paperformat">
@ -129,7 +139,11 @@
<field name="dpi">110</field>
</record>
<record id="action_report_general_ledger_qweb" model="ir.actions.report">
<record id="action_print_report_general_ledger_qweb" model="ir.actions.report">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
<record id="action_print_journal_ledger_wizard_qweb" model="ir.actions.report">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
@ -137,17 +151,15 @@
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
<record id="action_report_open_items_qweb" model="ir.actions.report">
<record id="action_print_report_open_items_qweb" model="ir.actions.report">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
<record id="action_report_aged_partner_balance_qweb"
model="ir.actions.report">
<record id="action_print_report_aged_partner_balance_qweb" model="ir.actions.report">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
<record id="action_report_vat_report_qweb"
model="ir.actions.report">
<record id="action_print_report_vat_report_qweb" model="ir.actions.report">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
</record>
@ -155,7 +167,7 @@
<record id="action_report_general_ledger_xlsx" model="ir.actions.report">
<field name="name">General Ledger XLSX</field>
<field name="model">report_general_ledger</field>
<field name="model">general.ledger.report.wizard</field>
<field name="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_general_ledger_xlsx</field>
<field name="report_type">xlsx</field>
@ -164,7 +176,7 @@
<record id="action_report_journal_ledger_xlsx" model="ir.actions.report">
<field name="name">Journal Ledger XLSX</field>
<field name="model">report_journal_ledger</field>
<field name="model">journal.ledger.report.wizard</field>
<field name="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_journal_ledger_xlsx</field>
<field name="report_type">xlsx</field>
@ -173,7 +185,7 @@
<record id="action_report_trial_balance_xlsx" model="ir.actions.report">
<field name="name">Trial Balance XLSX</field>
<field name="model">report_trial_balance</field>
<field name="model">trial.balance.report.wizard</field>
<field name="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_trial_balance_xlsx</field>
<field name="report_type">xlsx</field>
@ -182,7 +194,7 @@
<record id="action_report_open_items_xlsx" model="ir.actions.report">
<field name="name">Open Items XLSX</field>
<field name="model">report_open_items</field>
<field name="model">open.items.report.wizard</field>
<field name="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_open_items_xlsx</field>
<field name="report_type">xlsx</field>
@ -191,16 +203,16 @@
<record id="action_report_aged_partner_balance_xlsx" model="ir.actions.report">
<field name="name">Aged Partner Balance XLSX</field>
<field name="model">report_aged_partner_balance</field>
<field name="model">aged.partner.balance.report.wizard</field>
<field name="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_aged_partner_balance_xlsx</field>
<field name="report_type">xlsx</field>
<field name="report_file">report_aged_partner_balance</field>
</record>
<record id="action_report_vat_report_xlsx" model="ir.actions.report">
<field name="name">VAT Report XLSX</field>
<field name="model">report_vat_report</field>
<field name="model">vat.report.wizard</field>
<field name="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_vat_report_xlsx</field>
<field name="report_type">xlsx</field>

4
account_financial_report/tests/__init__.py

@ -2,10 +2,6 @@
# © 2016 Julien Coux (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-
from . import abstract_test
from . import abstract_test_tax_report
from . import abstract_test_foreign_currency
from . import test_aged_partner_balance
from . import test_general_ledger
from . import test_journal_ledger
from . import test_open_items

399
account_financial_report/tests/abstract_test.py

@ -1,399 +0,0 @@
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo.tests import common
from odoo.tools import test_reports
_logger = logging.getLogger(__name__)
class AbstractTest(common.TransactionCase):
"""Common technical tests for all reports."""
at_install = False
post_install = True
accounts = {}
def with_context(self, *args, **kwargs):
context = dict(args[0] if args else self.env.context, **kwargs)
self.env = self.env(context=context)
return self
def _chart_template_create(self):
transfer_account_id = self.env['account.account.template'].create({
'code': '000',
'name': 'Liquidity Transfers',
'reconcile': True,
'user_type_id': self.ref(
"account.data_account_type_current_assets"),
})
self.chart = self.env['account.chart.template'].create({
'name': 'Test COA',
'code_digits': 4,
'bank_account_code_prefix': 1014,
'cash_account_code_prefix': 1014,
'currency_id': self.ref('base.USD'),
'transfer_account_code_prefix': '000',
})
transfer_account_id.update({
'chart_template_id': self.chart.id,
})
self.env['ir.model.data'].create({
'res_id': transfer_account_id.id,
'model': transfer_account_id._name,
'name': 'Liquidity Transfers',
})
act = self.env['account.account.template'].create({
'code': '001',
'name': 'Expenses',
'user_type_id': self.ref("account.data_account_type_expenses"),
'chart_template_id': self.chart.id,
'reconcile': True,
})
self.env['ir.model.data'].create({
'res_id': act.id,
'model': act._name,
'name': 'expenses',
})
act = self.env['account.account.template'].create({
'code': '002',
'name': 'Product Sales',
'user_type_id': self.ref("account.data_account_type_revenue"),
'chart_template_id': self.chart.id,
'reconcile': True,
})
self.env['ir.model.data'].create({
'res_id': act.id,
'model': act._name,
'name': 'sales',
})
act = self.env['account.account.template'].create({
'code': '003',
'name': 'Account Receivable',
'user_type_id': self.ref("account.data_account_type_receivable"),
'chart_template_id': self.chart.id,
'reconcile': True,
})
self.env['ir.model.data'].create({
'res_id': act.id,
'model': act._name,
'name': 'receivable',
})
act = self.env['account.account.template'].create({
'code': '004',
'name': 'Account Payable',
'user_type_id': self.ref("account.data_account_type_payable"),
'chart_template_id': self.chart.id,
'reconcile': True,
})
self.env['ir.model.data'].create({
'res_id': act.id,
'model': act._name,
'name': 'payable',
})
def _add_chart_of_accounts(self):
self.company = self.env['res.company'].create({
'name': 'Spanish test company',
})
self.env.ref('base.group_multi_company').write({
'users': [(4, self.env.uid)],
})
self.env.user.write({
'company_ids': [(4, self.company.id)],
'company_id': self.company.id,
})
self.with_context(
company_id=self.company.id, force_company=self.company.id)
self.chart.try_loading_for_current_company()
self.revenue = self.env['account.account'].search(
[('user_type_id', '=', self.ref(
"account.data_account_type_revenue"))], limit=1)
self.expense = self.env['account.account'].search(
[('user_type_id', '=', self.ref(
"account.data_account_type_expenses"))], limit=1)
self.receivable = self.env['account.account'].search(
[('user_type_id', '=', self.ref(
"account.data_account_type_receivable"))], limit=1)
self.payable = self.env['account.account'].search(
[('user_type_id', '=', self.ref(
"account.data_account_type_payable"))], limit=1)
return True
def _journals_create(self):
self.journal_sale = self.env['account.journal'].create({
'company_id': self.company.id,
'name': 'Test journal for sale',
'type': 'sale',
'code': 'TSALE',
'default_debit_account_id': self.revenue.id,
'default_credit_account_id': self.revenue.id,
})
self.journal_purchase = self.env['account.journal'].create({
'company_id': self.company.id,
'name': 'Test journal for purchase',
'type': 'purchase',
'code': 'TPUR',
'default_debit_account_id': self.expense.id,
'default_credit_account_id': self.expense.id,
})
return True
def _invoice_create(self):
self.partner = self.env['res.partner'].create({
'name': 'Test partner',
'company_id': self.company.id,
'property_account_receivable_id': self.receivable.id,
'property_account_payable_id': self.payable.id,
})
# customer invoice
customer_invoice_lines = [(0, False, {
'name': 'Test description #1',
'account_id': self.revenue.id,
'quantity': 1.0,
'price_unit': 100.0,
}), (0, False, {
'name': 'Test description #2',
'account_id': self.revenue.id,
'quantity': 2.0,
'price_unit': 25.0,
})]
self.invoice_out = self.env['account.invoice'].create({
'partner_id': self.partner.id,
'type': 'out_invoice',
'invoice_line_ids': customer_invoice_lines,
'account_id': self.partner.property_account_receivable_id.id,
'journal_id': self.journal_sale.id,
})
self.invoice_out.action_invoice_open()
# vendor bill
vendor_invoice_lines = [(0, False, {
'name': 'Test description #1',
'account_id': self.revenue.id,
'quantity': 1.0,
'price_unit': 100.0,
}), (0, False, {
'name': 'Test description #2',
'account_id': self.revenue.id,
'quantity': 2.0,
'price_unit': 25.0,
})]
self.invoice_in = self.env['account.invoice'].create({
'partner_id': self.partner.id,
'type': 'in_invoice',
'invoice_line_ids': vendor_invoice_lines,
'account_id': self.partner.property_account_payable_id.id,
'journal_id': self.journal_purchase.id,
})
self.invoice_in.action_invoice_open()
def setUp(self):
super(AbstractTest, self).setUp()
self.with_context()
self._chart_template_create()
self._add_chart_of_accounts()
self._journals_create()
self._invoice_create()
self.model = self._getReportModel()
self.qweb_report_name = self._getQwebReportName()
self.xlsx_report_name = self._getXlsxReportName()
self.xlsx_action_name = self._getXlsxReportActionName()
self.report_title = self._getReportTitle()
self.base_filters = self._getBaseFilters()
self.additional_filters = self._getAdditionalFiltersToBeTested()
self.report = self.model.create(self.base_filters)
self.report.compute_data_for_report()
def test_html(self):
test_reports.try_report(self.env.cr, self.env.uid,
self.qweb_report_name,
[self.report.id],
report_type='qweb-html')
def test_qweb(self):
test_reports.try_report(self.env.cr, self.env.uid,
self.qweb_report_name,
[self.report.id],
report_type='qweb-pdf')
def test_xlsx(self):
test_reports.try_report(self.env.cr, self.env.uid,
self.xlsx_report_name,
[self.report.id],
report_type='xlsx')
def test_print(self):
self.report.print_report('qweb')
self.report.print_report('xlsx')
def test_02_generation_report_html(self):
"""Check if report HTML is correctly generated"""
# Check if returned report action is correct
report_type = 'qweb-html'
report_action = self.report.print_report(report_type)
self.assertDictContainsSubset(
{
'type': 'ir.actions.report',
'report_name': self.qweb_report_name,
'report_type': 'qweb-html',
},
report_action
)
# Check if report template is correct
report = self.env['ir.actions.report'].search(
[('report_name', '=', self.qweb_report_name),
('report_type', '=', report_type)], limit=1)
self.assertEqual(report.report_type, 'qweb-html')
rep = report.render(self.report.ids, {})
self.assertTrue(self.report_title.encode('utf8') in rep[0])
self.assertTrue(
self.report.account_ids[0].name.encode('utf8') in rep[0]
)
def test_04_compute_data(self):
"""Check that the SQL queries work with all filters options"""
for filters in [{}] + self.additional_filters:
current_filter = self.base_filters.copy()
current_filter.update(filters)
report = self.model.create(current_filter)
report.compute_data_for_report()
self.assertGreaterEqual(len(report.account_ids), 1)
# Same filters with only one account
current_filter = self.base_filters.copy()
current_filter.update(filters)
report_accounts = report.account_ids.filtered('account_id')
current_filter.update({
'filter_account_ids':
[(6, 0, report_accounts[0].account_id.ids)],
})
report2 = self.model.create(current_filter)
report2.compute_data_for_report()
self.assertEqual(len(report2.account_ids), 1)
self.assertEqual(report2.account_ids.name,
report_accounts[0].name)
if self._partner_test_is_possible(filters):
# Same filters with only one partner
report_partner_ids = report.account_ids.mapped('partner_ids')
partner_ids = report_partner_ids.mapped('partner_id')
current_filter = self.base_filters.copy()
current_filter.update(filters)
current_filter.update({
'filter_partner_ids': [(6, 0, partner_ids[0].ids)],
})
report3 = self.model.create(current_filter)
report3.compute_data_for_report()
self.assertGreaterEqual(len(report3.account_ids), 1)
report_partner_ids3 = report3.account_ids.mapped('partner_ids')
partner_ids3 = report_partner_ids3.mapped('partner_id')
self.assertEqual(len(partner_ids3), 1)
self.assertEqual(
partner_ids3.name,
partner_ids[0].name
)
# Same filters with only one partner and one account
report_partner_ids = report3.account_ids.mapped('partner_ids')
report_account_id = report_partner_ids.filtered(
lambda p: p.partner_id
)[0].report_account_id
current_filter = self.base_filters.copy()
current_filter.update(filters)
current_filter.update({
'filter_account_ids':
[(6, 0, report_account_id.account_id.ids)],
'filter_partner_ids': [(6, 0, partner_ids[0].ids)],
})
report4 = self.model.create(current_filter)
report4.compute_data_for_report()
self.assertEqual(len(report4.account_ids), 1)
self.assertEqual(report4.account_ids.name,
report_account_id.account_id.name)
report_partner_ids4 = report4.account_ids.mapped('partner_ids')
partner_ids4 = report_partner_ids4.mapped('partner_id')
self.assertEqual(len(partner_ids4), 1)
self.assertEqual(
partner_ids4.name,
partner_ids[0].name
)
def _partner_test_is_possible(self, filters):
"""
:return:
a boolean to indicate if partner test is possible
with current filters
"""
return True
def _getReportModel(self):
"""
:return: the report model name
"""
raise NotImplementedError()
def _getQwebReportName(self):
"""
:return: the qweb report name
"""
raise NotImplementedError()
def _getXlsxReportName(self):
"""
:return: the xlsx report name
"""
raise NotImplementedError()
def _getXlsxReportActionName(self):
"""
:return: the xlsx report action name
"""
raise NotImplementedError()
def _getReportTitle(self):
"""
:return: the report title displayed into the report
"""
raise NotImplementedError()
def _getBaseFilters(self):
"""
:return: the minimum required filters to generate report
"""
raise NotImplementedError()
def _getAdditionalFiltersToBeTested(self):
"""
:return: the additional filters to generate report variants
"""
raise NotImplementedError()

78
account_financial_report/tests/abstract_test_foreign_currency.py

@ -1,78 +0,0 @@
# Copyright 2018 Forest and Biomass Romania
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from . import abstract_test
_logger = logging.getLogger(__name__)
class AbstractTestForeignCurrency(abstract_test.AbstractTest):
"""Common technical tests for all reports."""
def _chart_template_create(self):
super(AbstractTestForeignCurrency, self)._chart_template_create()
# Account for foreign payments
self.account_type_other = self.env['account.account.type'].create(
{'name': 'foreign expenses',
'type': 'other',
})
act = self.env['account.account.template'].create({
'code': '0012',
'name': 'Foreign Expenses',
'user_type_id': self.account_type_other.id,
'chart_template_id': self.chart.id,
'currency_id': self.env.ref('base.EUR').id,
})
self.env['ir.model.data'].create({
'res_id': act.id,
'model': act._name,
'name': 'foreign expenses',
})
return True
def _add_chart_of_accounts(self):
super(AbstractTestForeignCurrency, self)._add_chart_of_accounts()
self.foreign_expense = self.env['account.account'].search(
[('currency_id', '=', self.env.ref('base.EUR').id)], limit=1)
self.foreign_currency_id = self.foreign_expense.currency_id
return True
def _journals_create(self):
super(AbstractTestForeignCurrency, self)._journals_create()
self.journal_foreign_purchases = self.env['account.journal'].create({
'company_id': self.company.id,
'name': 'Test journal for purchase',
'type': 'purchase',
'code': 'TFORPUR',
'default_debit_account_id': self.foreign_expense.id,
'default_credit_account_id': self.foreign_expense.id,
'currency_id': self.foreign_currency_id.id,
})
return True
def _invoice_create(self):
super(AbstractTestForeignCurrency, self)._invoice_create()
# vendor bill foreign currency
foreign_vendor_invoice_lines = [(0, False, {
'name': 'Test description #1',
'account_id': self.revenue.id,
'quantity': 1.0,
'price_unit': 100.0,
'currency_id': self.foreign_currency_id.id,
}), (0, False, {
'name': 'Test description #2',
'account_id': self.revenue.id,
'quantity': 2.0,
'price_unit': 25.0,
'currency_id': self.foreign_currency_id.id,
})]
self.foreign_invoice_in = self.env['account.invoice'].create({
'partner_id': self.partner.id,
'type': 'in_invoice',
'invoice_line_ids': foreign_vendor_invoice_lines,
'account_id': self.partner.property_account_payable_id.id,
'journal_id': self.journal_foreign_purchases.id,
})
self.foreign_invoice_in.action_invoice_open()
return True

75
account_financial_report/tests/abstract_test_tax_report.py

@ -1,75 +0,0 @@
# Copyright 2018 Forest and Biomass Romania
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import logging
from odoo.tests.common import TransactionCase
from odoo.tools import test_reports
_logger = logging.getLogger(__name__)
class AbstractTest(TransactionCase):
"""Common technical tests for all reports."""
def setUp(cls):
super(AbstractTest, cls).setUp()
cls.model = cls._getReportModel()
cls.qweb_report_name = cls._getQwebReportName()
cls.xlsx_report_name = cls._getXlsxReportName()
cls.xlsx_action_name = cls._getXlsxReportActionName()
cls.report_title = cls._getReportTitle()
cls.base_filters = cls._getBaseFilters()
cls.report = cls.model.create(cls.base_filters)
cls.report.compute_data_for_report()
def test_html(self):
test_reports.try_report(self.env.cr, self.env.uid,
self.qweb_report_name,
[self.report.id],
report_type='qweb-html')
def test_qweb(self):
test_reports.try_report(self.env.cr, self.env.uid,
self.qweb_report_name,
[self.report.id],
report_type='qweb-pdf')
def test_xlsx(self):
test_reports.try_report(self.env.cr, self.env.uid,
self.xlsx_report_name,
[self.report.id],
report_type='xlsx')
def test_print(self):
self.report.print_report('qweb')
self.report.print_report('xlsx')
def test_generation_report_html(self):
"""Check if report HTML is correctly generated"""
# Check if returned report action is correct
report_type = 'qweb-html'
report_action = self.report.print_report(report_type)
self.assertDictContainsSubset(
{
'type': 'ir.actions.report',
'report_name': self.qweb_report_name,
'report_type': 'qweb-html',
},
report_action
)
# Check if report template is correct
report = self.env['ir.actions.report'].search(
[('report_name', '=', self.qweb_report_name),
('report_type', '=', report_type)], limit=1)
self.assertEqual(report.report_type, 'qweb-html')
rep = report.render(self.report.ids, {})
self.assertTrue(self.report_title.encode('utf8') in rep[0])

41
account_financial_report/tests/test_aged_partner_balance.py

@ -1,41 +0,0 @@
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import date
from . import abstract_test
class TestAgedPartnerBalance(abstract_test.AbstractTest):
"""
Technical tests for Aged Partner Balance Report.
"""
def _getReportModel(self):
return self.env['report_aged_partner_balance']
def _getQwebReportName(self):
return 'account_financial_report.report_aged_partner_balance_qweb'
def _getXlsxReportName(self):
return 'a_f_r.report_aged_partner_balance_xlsx'
def _getXlsxReportActionName(self):
return 'account_financial_report.' \
'action_report_aged_partner_balance_xlsx'
def _getReportTitle(self):
return 'Odoo'
def _getBaseFilters(self):
return {
'date_at': date(date.today().year, 12, 31),
'company_id': self.company.id,
}
def _getAdditionalFiltersToBeTested(self):
return [
{'only_posted_moves': True},
{'show_move_line_details': True},
{'only_posted_moves': True, 'show_move_line_details': True},
]

561
account_financial_report/tests/test_general_ledger.py

@ -1,88 +1,13 @@
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import time
from odoo.tests import common
from odoo import fields
from odoo import fields, api
from datetime import date
from . import abstract_test_foreign_currency as a_t_f_c
class TestGeneralLedger(a_t_f_c.AbstractTestForeignCurrency):
"""
Technical tests for General Ledger Report.
"""
def _getReportModel(self):
return self.env['report_general_ledger']
def _getQwebReportName(self):
return 'account_financial_report.report_general_ledger_qweb'
def _getXlsxReportName(self):
return 'a_f_r.report_general_ledger_xlsx'
def _getXlsxReportActionName(self):
return 'account_financial_report.' \
'action_report_general_ledger_xlsx'
def _getReportTitle(self):
return 'Odoo'
def _getBaseFilters(self):
return {
'date_from': date(date.today().year, 1, 1),
'date_to': date(date.today().year, 12, 31),
'company_id': self.company.id,
'fy_start_date': date(date.today().year, 1, 1),
'foreign_currency': True,
}
def _getAdditionalFiltersToBeTested(self):
additional_filters = [
{'only_posted_moves': True},
{'hide_account_at_0': True},
{'centralize': True},
{'only_posted_moves': True, 'hide_account_at_0': True},
{'only_posted_moves': True, 'centralize': True},
{'hide_account_at_0': True, 'centralize': True},
{
'only_posted_moves': True,
'hide_account_at_0': True,
'centralize': True
},
]
# Add `show_analytic_tags` filter on each cases
additional_filters_with_show_tags = []
for additional_filter in additional_filters:
additional_filter['show_analytic_tags'] = True
additional_filters_with_show_tags.append(
additional_filter
)
additional_filters += additional_filters_with_show_tags
# Add `filter_analytic_tag_ids` filter on each cases
analytic_tag = self.env['account.analytic.tag'].create({
'name': 'TEST tag'
})
# Define all move lines on this tag
# (this test just check with the all filters, all works technically)
move_lines = self.env['account.move.line'].search([])
move_lines.write({
'analytic_tag_ids': [(6, False, analytic_tag.ids)],
})
additional_filters_with_filter_tags = []
for additional_filter in additional_filters:
additional_filter['filter_analytic_tag_ids'] = [
(6, False, analytic_tag.ids)
]
additional_filters_with_filter_tags.append(
additional_filter
)
additional_filters += additional_filters_with_filter_tags
return additional_filters
class TestGeneralLedgerReport(common.TransactionCase):
@ -106,6 +31,7 @@ class TestGeneralLedgerReport(common.TransactionCase):
'=',
self.env.ref('account.data_unaffected_earnings').id
)], limit=1)
self.partner = self.env.ref('base.res_partner_12')
def _add_move(
self,
@ -148,47 +74,92 @@ class TestGeneralLedgerReport(common.TransactionCase):
move.post()
def _get_report_lines(self, with_partners=False):
centralize = True
if with_partners:
centralize = False
company = self.env.ref('base.main_company')
general_ledger = self.env['report_general_ledger'].create({
general_ledger = self.env['general.ledger.report.wizard'].create({
'date_from': self.fy_date_start,
'date_to': self.fy_date_end,
'only_posted_moves': True,
'target_move': 'posted',
'hide_account_at_0': False,
'company_id': company.id,
'fy_start_date': self.fy_date_start,
'centralize': centralize,
})
general_ledger.compute_data_for_report(
with_line_details=True, with_partners=with_partners
)
lines = {}
report_account_model = self.env['report_general_ledger_account']
lines['receivable'] = report_account_model.search([
('report_id', '=', general_ledger.id),
('account_id', '=', self.receivable_account.id),
])
lines['income'] = report_account_model.search([
('report_id', '=', general_ledger.id),
('account_id', '=', self.income_account.id),
])
lines['unaffected'] = report_account_model.search([
('report_id', '=', general_ledger.id),
('account_id', '=', self.unaffected_account.id),
])
if with_partners:
report_partner_model = self.env[
'report_general_ledger_partner'
]
lines['partner_receivable'] = report_partner_model.search([
('report_account_id', '=', lines['receivable'].id),
('partner_id', '=', self.env.ref('base.res_partner_12').id),
])
return lines
data = general_ledger._prepare_report_general_ledger()
res_data = self.env[
'report.account_financial_report.general_ledger'
]._get_report_values(general_ledger, data)
return res_data
@api.model
def check_account_in_report(self, account_id, general_ledger):
account_in_report = False
for account in general_ledger:
if account['id'] == account_id:
account_in_report = True
break
return account_in_report
@api.model
def check_partner_in_report(self, account_id, partner_id, general_ledger):
partner_in_report = False
for account in general_ledger:
if account['id'] == account_id and account['partners']:
for partner in account['list_partner']:
if partner['id'] == partner_id:
partner_in_report = True
return partner_in_report
@api.model
def _get_initial_balance(self, account_id, general_ledger):
initial_balance = False
for account in general_ledger:
if account['id'] == account_id:
initial_balance = account['init_bal']
return initial_balance
@api.model
def _get_partner_initial_balance(self, account_id, partner_id,
general_ledger):
initial_balance = False
for account in general_ledger:
if account['id'] == account_id and account['partners']:
for partner in account['list_partner']:
if partner['id'] == partner_id:
initial_balance = partner['init_bal']
return initial_balance
@api.model
def _get_final_balance(self, account_id, general_ledger):
final_balance = False
for account in general_ledger:
if account['id'] == account_id:
final_balance = account['fin_bal']
return final_balance
@api.model
def _get_partner_final_balance(
self, account_id, partner_id, general_ledger):
final_balance = False
for account in general_ledger:
if account['id'] == account_id and account['partners']:
for partner in account['list_partner']:
if partner['id'] == partner_id:
final_balance = partner['fin_bal']
return final_balance
def test_01_account_balance(self):
# Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['receivable']), 0)
self.assertEqual(len(lines['income']), 0)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_receivable_account = self.check_account_in_report(
self.receivable_account.id, general_ledger)
self.assertFalse(check_receivable_account)
check_income_account = self.check_account_in_report(
self.income_account.id, general_ledger)
self.assertFalse(check_income_account)
# Add a move at the previous day of the first day of fiscal year
# to check the initial balance
@ -201,17 +172,27 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 0)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_receivable_account = self.check_account_in_report(
self.receivable_account.id, general_ledger)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.income_account.id, general_ledger)
self.assertFalse(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_debit, 1000)
self.assertEqual(lines['receivable'].initial_credit, 0)
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].final_debit, 1000)
self.assertEqual(lines['receivable'].final_credit, 0)
self.assertEqual(lines['receivable'].final_balance, 1000)
receivable_init_balance = self._get_initial_balance(
self.receivable_account.id, general_ledger)
receivable_fin_balance = self._get_final_balance(
self.receivable_account.id, general_ledger)
self.assertEqual(receivable_init_balance['debit'], 1000)
self.assertEqual(receivable_init_balance['credit'], 0)
self.assertEqual(receivable_init_balance['balance'], 1000)
self.assertEqual(receivable_fin_balance['debit'], 1000)
self.assertEqual(receivable_fin_balance['credit'], 0)
self.assertEqual(receivable_fin_balance['balance'], 1000)
# Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -225,24 +206,38 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_receivable_account = self.check_account_in_report(
self.receivable_account.id, general_ledger)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.income_account.id, general_ledger)
self.assertTrue(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_debit, 1000)
self.assertEqual(lines['receivable'].initial_credit, 0)
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].final_debit, 1000)
self.assertEqual(lines['receivable'].final_credit, 1000)
self.assertEqual(lines['receivable'].final_balance, 0)
self.assertEqual(lines['income'].initial_debit, 0)
self.assertEqual(lines['income'].initial_credit, 0)
self.assertEqual(lines['income'].initial_balance, 0)
self.assertEqual(lines['income'].final_debit, 1000)
self.assertEqual(lines['income'].final_credit, 0)
self.assertEqual(lines['income'].final_balance, 1000)
receivable_init_balance = self._get_initial_balance(
self.receivable_account.id, general_ledger)
receivable_fin_balance = self._get_final_balance(
self.receivable_account.id, general_ledger)
income_init_balance = self._get_initial_balance(
self.income_account.id, general_ledger)
income_fin_balance = self._get_final_balance(
self.income_account.id, general_ledger)
self.assertEqual(receivable_init_balance['debit'], 1000)
self.assertEqual(receivable_init_balance['credit'], 0)
self.assertEqual(receivable_init_balance['balance'], 1000)
self.assertEqual(receivable_fin_balance['debit'], 1000)
self.assertEqual(receivable_fin_balance['credit'], 1000)
self.assertEqual(receivable_fin_balance['balance'], 0)
self.assertEqual(income_init_balance['debit'], 0)
self.assertEqual(income_init_balance['credit'], 0)
self.assertEqual(income_init_balance['balance'], 0)
self.assertEqual(income_fin_balance['debit'], 1000)
self.assertEqual(income_fin_balance['credit'], 0)
self.assertEqual(income_fin_balance['balance'], 1000)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
@ -255,29 +250,46 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_receivable_account = self.check_account_in_report(
self.receivable_account.id, general_ledger)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.income_account.id, general_ledger)
self.assertTrue(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_debit, 1000)
self.assertEqual(lines['receivable'].initial_credit, 0)
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].final_debit, 1000)
self.assertEqual(lines['receivable'].final_credit, 2000)
self.assertEqual(lines['receivable'].final_balance, -1000)
self.assertEqual(lines['income'].initial_debit, 0)
self.assertEqual(lines['income'].initial_credit, 0)
self.assertEqual(lines['income'].initial_balance, 0)
self.assertEqual(lines['income'].final_debit, 2000)
self.assertEqual(lines['income'].final_credit, 0)
self.assertEqual(lines['income'].final_balance, 2000)
receivable_init_balance = self._get_initial_balance(
self.receivable_account.id, general_ledger)
receivable_fin_balance = self._get_final_balance(
self.receivable_account.id, general_ledger)
income_init_balance = self._get_initial_balance(
self.income_account.id, general_ledger)
income_fin_balance = self._get_final_balance(
self.income_account.id, general_ledger)
self.assertEqual(receivable_init_balance['debit'], 1000)
self.assertEqual(receivable_init_balance['credit'], 0)
self.assertEqual(receivable_init_balance['balance'], 1000)
self.assertEqual(receivable_fin_balance['debit'], 1000)
self.assertEqual(receivable_fin_balance['credit'], 2000)
self.assertEqual(receivable_fin_balance['balance'], -1000)
self.assertEqual(income_init_balance['debit'], 0)
self.assertEqual(income_init_balance['credit'], 0)
self.assertEqual(income_init_balance['balance'], 0)
self.assertEqual(income_fin_balance['debit'], 2000)
self.assertEqual(income_fin_balance['credit'], 0)
self.assertEqual(income_fin_balance['balance'], 2000)
def test_02_partner_balance(self):
# Generate the general ledger line
lines = self._get_report_lines(with_partners=True)
self.assertEqual(len(lines['partner_receivable']), 0)
res_data = self._get_report_lines(with_partners=True)
general_ledger = res_data['general_ledger']
check_partner = self.check_partner_in_report(
self.receivable_account.id, self.partner.id, general_ledger)
self.assertFalse(check_partner)
# Add a move at the previous day of the first day of fiscal year
# to check the initial balance
@ -290,16 +302,26 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines(with_partners=True)
self.assertEqual(len(lines['partner_receivable']), 1)
res_data = self._get_report_lines(with_partners=True)
general_ledger = res_data['general_ledger']
check_partner = self.check_partner_in_report(
self.receivable_account.id, self.partner.id, general_ledger)
self.assertTrue(check_partner)
# Check the initial and final balance
self.assertEqual(lines['partner_receivable'].initial_debit, 1000)
self.assertEqual(lines['partner_receivable'].initial_credit, 0)
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
self.assertEqual(lines['partner_receivable'].final_debit, 1000)
self.assertEqual(lines['partner_receivable'].final_credit, 0)
self.assertEqual(lines['partner_receivable'].final_balance, 1000)
partner_initial_balance = self._get_partner_initial_balance(
self.receivable_account.id, self.partner.id, general_ledger
)
partner_final_balance = self._get_partner_final_balance(
self.receivable_account.id, self.partner.id, general_ledger
)
self.assertEqual(partner_initial_balance['debit'], 1000)
self.assertEqual(partner_initial_balance['credit'], 0)
self.assertEqual(partner_initial_balance['balance'], 1000)
self.assertEqual(partner_final_balance['debit'], 1000)
self.assertEqual(partner_final_balance['credit'], 0)
self.assertEqual(partner_final_balance['balance'], 1000)
# Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -313,16 +335,26 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines(with_partners=True)
self.assertEqual(len(lines['partner_receivable']), 1)
res_data = self._get_report_lines(with_partners=True)
general_ledger = res_data['general_ledger']
check_partner = self.check_partner_in_report(
self.receivable_account.id, self.partner.id, general_ledger)
self.assertTrue(check_partner)
# Check the initial and final balance
self.assertEqual(lines['partner_receivable'].initial_debit, 1000)
self.assertEqual(lines['partner_receivable'].initial_credit, 0)
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
self.assertEqual(lines['partner_receivable'].final_debit, 1000)
self.assertEqual(lines['partner_receivable'].final_credit, 1000)
self.assertEqual(lines['partner_receivable'].final_balance, 0)
partner_initial_balance = self._get_partner_initial_balance(
self.receivable_account.id, self.partner.id, general_ledger
)
partner_final_balance = self._get_partner_final_balance(
self.receivable_account.id, self.partner.id, general_ledger
)
self.assertEqual(partner_initial_balance['debit'], 1000)
self.assertEqual(partner_initial_balance['credit'], 0)
self.assertEqual(partner_initial_balance['balance'], 1000)
self.assertEqual(partner_final_balance['debit'], 1000)
self.assertEqual(partner_final_balance['credit'], 1000)
self.assertEqual(partner_final_balance['balance'], 0)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
@ -335,29 +367,47 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines(with_partners=True)
self.assertEqual(len(lines['partner_receivable']), 1)
res_data = self._get_report_lines(with_partners=True)
general_ledger = res_data['general_ledger']
check_partner = self.check_partner_in_report(
self.receivable_account.id, self.partner.id, general_ledger)
self.assertTrue(check_partner)
# Check the initial and final balance
self.assertEqual(lines['partner_receivable'].initial_debit, 1000)
self.assertEqual(lines['partner_receivable'].initial_credit, 0)
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
self.assertEqual(lines['partner_receivable'].final_debit, 1000)
self.assertEqual(lines['partner_receivable'].final_credit, 2000)
self.assertEqual(lines['partner_receivable'].final_balance, -1000)
partner_initial_balance = self._get_partner_initial_balance(
self.receivable_account.id, self.partner.id, general_ledger
)
partner_final_balance = self._get_partner_final_balance(
self.receivable_account.id, self.partner.id, general_ledger
)
self.assertEqual(partner_initial_balance['debit'], 1000)
self.assertEqual(partner_initial_balance['credit'], 0)
self.assertEqual(partner_initial_balance['balance'], 1000)
self.assertEqual(partner_final_balance['debit'], 1000)
self.assertEqual(partner_final_balance['credit'], 2000)
self.assertEqual(partner_final_balance['balance'], -1000)
def test_03_unaffected_account_balance(self):
# Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['unaffected']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_balance, 0)
self.assertEqual(lines['unaffected'].final_debit, 0)
self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_balance, 0)
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
self.assertEqual(unaffected_init_balance['debit'], 0)
self.assertEqual(unaffected_init_balance['credit'], 0)
self.assertEqual(unaffected_init_balance['balance'], 0)
self.assertEqual(unaffected_fin_balance['debit'], 0)
self.assertEqual(unaffected_fin_balance['credit'], 0)
self.assertEqual(unaffected_fin_balance['balance'], 0)
# Add a move at the previous day of the first day of fiscal year
# to check the initial balance
@ -370,16 +420,24 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['unaffected']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 1000)
self.assertEqual(lines['unaffected'].initial_balance, -1000)
self.assertEqual(lines['unaffected'].final_debit, 0)
self.assertEqual(lines['unaffected'].final_credit, 1000)
self.assertEqual(lines['unaffected'].final_balance, -1000)
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
self.assertEqual(unaffected_init_balance['debit'], 0)
self.assertEqual(unaffected_init_balance['credit'], 1000)
self.assertEqual(unaffected_init_balance['balance'], -1000)
self.assertEqual(unaffected_fin_balance['debit'], 0)
self.assertEqual(unaffected_fin_balance['credit'], 1000)
self.assertEqual(unaffected_fin_balance['balance'], -1000)
# Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -395,16 +453,24 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['unaffected']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 1000)
self.assertEqual(lines['unaffected'].initial_balance, -1000)
self.assertEqual(lines['unaffected'].final_debit, 1000)
self.assertEqual(lines['unaffected'].final_credit, 1000)
self.assertEqual(lines['unaffected'].final_balance, 0)
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
self.assertEqual(unaffected_init_balance['debit'], 0)
self.assertEqual(unaffected_init_balance['credit'], 1000)
self.assertEqual(unaffected_init_balance['balance'], -1000)
self.assertEqual(unaffected_fin_balance['debit'], 1000)
self.assertEqual(unaffected_fin_balance['credit'], 1000)
self.assertEqual(unaffected_fin_balance['balance'], 0)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
@ -419,29 +485,45 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['unaffected']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 1000)
self.assertEqual(lines['unaffected'].initial_balance, -1000)
self.assertEqual(lines['unaffected'].final_debit, 1000)
self.assertEqual(lines['unaffected'].final_credit, 4000)
self.assertEqual(lines['unaffected'].final_balance, -3000)
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
self.assertEqual(unaffected_init_balance['debit'], 0)
self.assertEqual(unaffected_init_balance['credit'], 1000)
self.assertEqual(unaffected_init_balance['balance'], -1000)
self.assertEqual(unaffected_fin_balance['debit'], 1000)
self.assertEqual(unaffected_fin_balance['credit'], 4000)
self.assertEqual(unaffected_fin_balance['balance'], -3000)
def test_04_unaffected_account_balance_2_years(self):
# Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['unaffected']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 0)
self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_balance, 0)
self.assertEqual(lines['unaffected'].final_debit, 0)
self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_balance, 0)
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
self.assertEqual(unaffected_init_balance['debit'], 0)
self.assertEqual(unaffected_init_balance['credit'], 0)
self.assertEqual(unaffected_init_balance['balance'], 0)
self.assertEqual(unaffected_fin_balance['debit'], 0)
self.assertEqual(unaffected_fin_balance['credit'], 0)
self.assertEqual(unaffected_fin_balance['balance'], 0)
# Add a move at any date 2 years before the balance
# (to create an historic)
@ -454,16 +536,24 @@ class TestGeneralLedgerReport(common.TransactionCase):
)
# Re Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['unaffected']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 1000)
self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_balance, 1000)
self.assertEqual(lines['unaffected'].final_debit, 1000)
self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_balance, 1000)
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
self.assertEqual(unaffected_init_balance['debit'], 1000)
self.assertEqual(unaffected_init_balance['credit'], 0)
self.assertEqual(unaffected_init_balance['balance'], 1000)
self.assertEqual(unaffected_fin_balance['debit'], 1000)
self.assertEqual(unaffected_fin_balance['credit'], 0)
self.assertEqual(unaffected_fin_balance['balance'], 1000)
# Affect the company's result last year
self._add_move(
@ -486,17 +576,26 @@ class TestGeneralLedgerReport(common.TransactionCase):
unaffected_debit=0,
unaffected_credit=0
)
# Re Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['unaffected']), 1)
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
self.assertEqual(lines['unaffected'].initial_debit, 500)
self.assertEqual(lines['unaffected'].initial_credit, 0)
self.assertEqual(lines['unaffected'].initial_balance, 500)
self.assertEqual(lines['unaffected'].final_debit, 500)
self.assertEqual(lines['unaffected'].final_credit, 0)
self.assertEqual(lines['unaffected'].final_balance, 500)
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
self.assertEqual(unaffected_init_balance['debit'], 1500)
self.assertEqual(unaffected_init_balance['credit'], 1000)
self.assertEqual(unaffected_init_balance['balance'], 500)
self.assertEqual(unaffected_fin_balance['debit'], 1500)
self.assertEqual(unaffected_fin_balance['credit'], 1000)
self.assertEqual(unaffected_fin_balance['balance'], 500)
def test_partner_filter(self):
partner_1 = self.env.ref('base.res_partner_1')

206
account_financial_report/tests/test_journal_ledger.py

@ -1,83 +1,13 @@
# Copyright 2017 ACSONE SA/NV
# Copyright 2019-20 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import datetime, date
from datetime import datetime
from dateutil.relativedelta import relativedelta
from odoo.fields import Date
from odoo.tests.common import TransactionCase
from . import abstract_test_foreign_currency as a_t_f_c
class TestJournalLedger(a_t_f_c.AbstractTestForeignCurrency):
"""
Technical tests for General Ledger Report.
"""
def _getReportModel(self):
return self.env['report_journal_ledger']
def _getQwebReportName(self):
return 'account_financial_report.report_journal_ledger_qweb'
def _getXlsxReportName(self):
return 'a_f_r.report_journal_ledger_xlsx'
def _getXlsxReportActionName(self):
return 'account_financial_report.' \
'action_report_journal_ledger_xlsx'
def _getReportTitle(self):
return 'Odoo'
def _getBaseFilters(self):
return {
'date_from': date(date.today().year, 1, 1),
'date_to': date(date.today().year, 12, 31),
'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)]
}
def _getAdditionalFiltersToBeTested(self):
return [
{'move_target': "All",
'sort_option': "Date",
'group_option': "Journal",
'with_account_name': True,
'foreign_currency': True},
]
def test_02_generation_report_html(self):
"""Check if report HTML is correctly generated"""
# Check if returned report action is correct
report_type = 'qweb-html'
report_action = self.report.print_report(report_type)
self.assertDictContainsSubset(
{
'type': 'ir.actions.report',
'report_name': self.qweb_report_name,
'report_type': 'qweb-html',
},
report_action
)
# Check if report template is correct
report = self.env['ir.actions.report'].search(
[('report_name', '=', self.qweb_report_name),
('report_type', '=', report_type)], limit=1)
self.assertEqual(report.report_type, 'qweb-html')
rep = report.render(self.report.ids, {})
self.assertTrue(self.report_title.encode('utf8') in rep[0])
self.assertTrue(
self.report.journal_ids[0].name.encode('utf8') in rep[0]
)
def test_04_compute_data(self):
return True
class TestJournalReport(TransactionCase):
@ -86,11 +16,13 @@ class TestJournalReport(TransactionCase):
self.AccountObj = self.env['account.account']
self.InvoiceObj = self.env['account.invoice']
self.JournalObj = self.env['account.journal']
self.JournalReportObj = self.env['journal.ledger.report.wizard']
self.MoveObj = self.env['account.move']
self.ReportJournalLedger = self.env['report_journal_ledger']
self.TaxObj = self.env['account.tax']
self.JournalLedgerReportWizard = self.env[
'journal.ledger.report.wizard']
self.JournalLedgerReport = \
self.env['report.account_financial_report.journal_ledger']
self.company = self.env.ref('base.main_company')
today = datetime.today()
@ -191,52 +123,50 @@ class TestJournalReport(TransactionCase):
return self.MoveObj.create(move_vals)
def check_report_journal_debit_credit(
self, report, expected_debit, expected_credit):
self, res_data, expected_debit, expected_credit):
self.assertEqual(
expected_debit,
sum([journal.debit for journal in
report.report_journal_ledger_ids])
sum([rec['debit'] for rec in res_data['Journal_Ledgers']])
)
self.assertEqual(
expected_credit,
sum([journal.credit for journal in
report.report_journal_ledger_ids])
sum([rec['credit'] for rec in res_data['Journal_Ledgers']])
)
def check_report_journal_debit_credit_taxes(
self, report,
self, res_data,
expected_base_debit, expected_base_credit,
expected_tax_debit, expected_tax_credit):
self.assertEqual(
expected_base_debit,
sum([
journal.base_debit
for journal in report.report_journal_ledger_tax_line_ids
])
)
self.assertEqual(
expected_base_credit,
sum([
journal.base_credit
for journal in report.report_journal_ledger_tax_line_ids
])
)
self.assertEqual(
expected_tax_debit,
sum([
journal.tax_debit
for journal in report.report_journal_ledger_tax_line_ids
])
)
self.assertEqual(
expected_tax_credit,
sum([
journal.tax_credit
for journal in report.report_journal_ledger_tax_line_ids
])
)
for rec in res_data['Journal_Ledgers']:
self.assertEqual(
expected_base_debit,
sum([
tax_line['base_debit']
for tax_line in rec['tax_lines']
])
)
self.assertEqual(
expected_base_credit,
sum([
tax_line['base_credit']
for tax_line in rec['tax_lines']
])
)
self.assertEqual(
expected_tax_debit,
sum([
tax_line['tax_debit']
for tax_line in rec['tax_lines']
])
)
self.assertEqual(
expected_tax_credit,
sum([
tax_line['tax_credit']
for tax_line in rec['tax_lines']
])
)
def test_01_test_total(self):
today_date = Date.today()
@ -250,42 +180,43 @@ class TestJournalReport(TransactionCase):
last_year_date, self.journal_sale,
0, 100, 100, 0)
report = self.ReportJournalLedger.create({
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start,
'date_to': self.fy_date_end,
'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)]
})
report.compute_data_for_report()
self.check_report_journal_debit_credit(report, 100, 100)
data = wiz._prepare_report_journal_ledger()
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 100, 100)
move3 = self._add_move(
today_date, self.journal_sale,
0, 100, 100, 0)
report.compute_data_for_report()
self.check_report_journal_debit_credit(report, 200, 200)
report.move_target = 'posted'
report.compute_data_for_report()
self.check_report_journal_debit_credit(report, 0, 0)
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 200, 200)
wiz.move_target = 'posted'
data = wiz._prepare_report_journal_ledger()
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 0, 0)
move1.post()
report.compute_data_for_report()
self.check_report_journal_debit_credit(report, 100, 100)
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 100, 100)
move2.post()
report.compute_data_for_report()
self.check_report_journal_debit_credit(report, 100, 100)
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 100, 100)
move3.post()
report.compute_data_for_report()
self.check_report_journal_debit_credit(report, 200, 200)
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 200, 200)
report.date_from = self.previous_fy_date_start
report.compute_data_for_report()
self.check_report_journal_debit_credit(report, 300, 300)
wiz.date_from = self.previous_fy_date_start
data = wiz._prepare_report_journal_ledger()
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 300, 300)
def test_02_test_taxes_out_invoice(self):
invoice_values = {
@ -314,16 +245,16 @@ class TestJournalReport(TransactionCase):
invoice = self.InvoiceObj.create(invoice_values)
invoice.action_invoice_open()
report = self.ReportJournalLedger.create({
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start,
'date_to': self.fy_date_end,
'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)]
})
report.compute_data_for_report()
self.check_report_journal_debit_credit(report, 250, 250)
self.check_report_journal_debit_credit_taxes(report, 0, 300, 0, 50)
data = wiz._prepare_report_journal_ledger()
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 250, 250)
self.check_report_journal_debit_credit_taxes(res_data, 0, 300, 0, 50)
def test_03_test_taxes_in_invoice(self):
invoice_values = {
@ -352,13 +283,14 @@ class TestJournalReport(TransactionCase):
invoice = self.InvoiceObj.create(invoice_values)
invoice.action_invoice_open()
report = self.ReportJournalLedger.create({
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start,
'date_to': self.fy_date_end,
'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)]
})
report.compute_data_for_report()
data = wiz._prepare_report_journal_ledger()
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(report, 250, 250)
self.check_report_journal_debit_credit_taxes(report, 300, 0, 50, 0)
self.check_report_journal_debit_credit(res_data, 250, 250)
self.check_report_journal_debit_credit_taxes(res_data, 300, 0, 50, 0)

37
account_financial_report/tests/test_open_items.py

@ -2,43 +2,10 @@
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import date
from . import abstract_test_foreign_currency as a_t_f_c
from odoo.tests.common import TransactionCase
class TestOpenItems(a_t_f_c.AbstractTestForeignCurrency):
"""
Technical tests for Open Items Report.
"""
def _getReportModel(self):
return self.env['report_open_items']
def _getQwebReportName(self):
return 'account_financial_report.report_open_items_qweb'
def _getXlsxReportName(self):
return 'a_f_r.report_open_items_xlsx'
def _getXlsxReportActionName(self):
return 'account_financial_report.action_report_open_items_xlsx'
def _getReportTitle(self):
return 'Odoo'
def _getBaseFilters(self):
return {
'date_at': date(date.today().year, 12, 31),
'company_id': self.company.id,
'foreign_currency': True,
}
def _getAdditionalFiltersToBeTested(self):
return [
{'only_posted_moves': True},
{'hide_account_at_0': True},
{'only_posted_moves': True, 'hide_account_at_0': True},
]
class TestOpenItems(TransactionCase):
def test_partner_filter(self):
partner_1 = self.env.ref('base.res_partner_1')

649
account_financial_report/tests/test_trial_balance.py

@ -1,65 +1,9 @@
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import date
from odoo.tests import common
from . import abstract_test_foreign_currency as a_t_f_c
class TestTrialBalance(a_t_f_c.AbstractTestForeignCurrency):
"""
Technical tests for Trial Balance Report.
"""
def _getReportModel(self):
return self.env['report_trial_balance']
def _getQwebReportName(self):
return 'account_financial_report.report_trial_balance_qweb'
def _getXlsxReportName(self):
return 'a_f_r.report_trial_balance_xlsx'
def _getXlsxReportActionName(self):
return 'account_financial_report.action_report_trial_balance_xlsx'
def _getReportTitle(self):
return 'Odoo'
def _getBaseFilters(self):
return {
'date_from': date(date.today().year, 1, 1),
'date_to': date(date.today().year, 12, 31),
'company_id': self.company.id,
'fy_start_date': date(date.today().year, 1, 1),
'foreign_currency': True,
'show_partner_details': True,
}
def _getAdditionalFiltersToBeTested(self):
return [
{'only_posted_moves': True},
{'hide_account_at_0': True},
{'show_partner_details': True},
{'hierarchy_on': 'computed'},
{'hierarchy_on': 'relation'},
{'only_posted_moves': True, 'hide_account_at_0': True,
'hierarchy_on': 'computed'},
{'only_posted_moves': True, 'hide_account_at_0': True,
'hierarchy_on': 'relation'},
{'only_posted_moves': True, 'hide_account_at_0': True},
{'only_posted_moves': True, 'show_partner_details': True},
{'hide_account_at_0': True, 'show_partner_details': True},
{
'only_posted_moves': True,
'hide_account_at_0': True,
'show_partner_details': True
},
]
def _partner_test_is_possible(self, filters):
return 'show_partner_details' in filters
class TestTrialBalanceReport(common.TransactionCase):
@ -114,6 +58,13 @@ class TestTrialBalanceReport(common.TransactionCase):
self.fy_date_end = '2016-12-31'
self.date_start = '2016-01-01'
self.date_end = '2016-12-31'
self.partner = self.env.ref('base.res_partner_12')
self.unaffected_account = self.env['account.account'].search([
(
'user_type_id',
'=',
self.env.ref('account.data_unaffected_earnings').id
)], limit=1)
def _add_move(
self,
@ -169,49 +120,81 @@ class TestTrialBalanceReport(common.TransactionCase):
def _get_report_lines(self, with_partners=False, hierarchy_on='computed'):
company = self.env.ref('base.main_company')
trial_balance = self.env['report_trial_balance'].create({
trial_balance = self.env['trial.balance.report.wizard'].create({
'date_from': self.date_start,
'date_to': self.date_end,
'only_posted_moves': True,
'hide_account_at_0': False,
'target_move': 'posted',
'hide_account_at_0': True,
'hierarchy_on': hierarchy_on,
'company_id': company.id,
'fy_start_date': self.fy_date_start,
'show_partner_details': with_partners,
})
trial_balance.compute_data_for_report()
lines = {}
report_account_model = self.env['report_trial_balance_account']
lines['receivable'] = report_account_model.search([
('report_id', '=', trial_balance.id),
('account_id', '=', self.account100.id),
])
lines['income'] = report_account_model.search([
('report_id', '=', trial_balance.id),
('account_id', '=', self.account200.id),
])
lines['unaffected'] = report_account_model.search([
('report_id', '=', trial_balance.id),
('account_id', '=', self.account110.id),
])
lines['group1'] = report_account_model.search([
('report_id', '=', trial_balance.id),
('account_group_id', '=', self.group1.id),
])
lines['group2'] = report_account_model.search([
('report_id', '=', trial_balance.id),
('account_group_id', '=', self.group2.id),
])
if with_partners:
report_partner_model = self.env[
'report_trial_balance_partner'
]
lines['partner_receivable'] = report_partner_model.search([
('report_account_id', '=', lines['receivable'].id),
('partner_id', '=', self.env.ref('base.res_partner_12').id),
])
data = trial_balance._prepare_report_trial_balance()
res_data = self.env[
'report.account_financial_report.trial_balance']._get_report_values(
trial_balance, data)
return res_data
def check_account_in_report(self, account_id, trial_balance):
account_in_report = False
for account in trial_balance:
if account['id'] == account_id and account['type'] == 'account_type':
account_in_report = True
break
return account_in_report
def _get_account_lines(self, account_id, trial_balance):
lines = False
for account in trial_balance:
if account['id'] == account_id and account['type'] == 'account_type':
lines = {
'initial_balance': account['initial_balance'],
'debit': account['debit'],
'credit': account['credit'],
'final_balance': account['ending_balance']
}
return lines
def _get_group_lines(self, group_id, trial_balance):
lines = False
for group in trial_balance:
if group['id'] == group_id and group['type'] == 'group_type':
lines = {
'initial_balance': group['initial_balance'],
'debit': group['debit'],
'credit': group['credit'],
'final_balance': group['ending_balance']
}
return lines
def check_partner_in_report(self, account_id, partner_id, total_amount):
partner_in_report = False
if account_id in total_amount.keys():
if partner_id in total_amount[account_id]:
partner_in_report = True
return partner_in_report
def _get_partner_lines(self, account_id, partner_id, total_amount):
acc_id = account_id
prt_id = partner_id
lines = {
'initial_balance': total_amount[acc_id][prt_id]['initial_balance'],
'debit': total_amount[acc_id][prt_id]['debit'],
'credit': total_amount[acc_id][prt_id]['credit'],
'final_balance': total_amount[acc_id][prt_id]['ending_balance'],
}
return lines
def _sum_all_accounts(self, trial_balance, feature):
total = 0.0
for account in trial_balance:
if account['type'] == 'account_type':
for key in account.keys():
if key == feature:
total += account[key]
return total
def test_00_account_group(self):
self.assertGreaterEqual(len(self.group1.compute_account_ids), 19)
self.assertGreaterEqual(len(self.group2.compute_account_ids), 9)
@ -227,9 +210,15 @@ class TestTrialBalanceReport(common.TransactionCase):
if acc.code.startswith('1') or acc.code.startswith('2'):
acc.code = '999' + acc.code
# Generate the general ledger line
lines = self._get_report_lines()
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines()
trial_balance = res_data['trial_balance']
check_receivable_account = self.check_account_in_report(
self.account100.id, trial_balance)
self.assertFalse(check_receivable_account)
check_income_account = self.check_account_in_report(
self.account200.id, trial_balance)
self.assertFalse(check_income_account)
# Add a move at the previous day of the first day of fiscal year
# to check the initial balance
@ -242,20 +231,29 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines()
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines()
trial_balance = res_data['trial_balance']
check_receivable_account = self.check_account_in_report(
self.account100.id, trial_balance)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.account200.id, trial_balance)
self.assertFalse(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].debit, 0)
self.assertEqual(lines['receivable'].credit, 0)
self.assertEqual(lines['receivable'].final_balance, 1000)
account_receivable_lines = self._get_account_lines(
self.account100.id, trial_balance)
group1_lines = self._get_group_lines(self.group1.id, trial_balance)
self.assertEqual(lines['group1'].initial_balance, 1000)
self.assertEqual(lines['group1'].debit, 0)
self.assertEqual(lines['group1'].credit, 0)
self.assertEqual(lines['group1'].final_balance, 1000)
self.assertEqual(account_receivable_lines['initial_balance'], 1000)
self.assertEqual(account_receivable_lines['debit'], 0)
self.assertEqual(account_receivable_lines['credit'], 0)
self.assertEqual(account_receivable_lines['final_balance'], 1000)
self.assertEqual(group1_lines['initial_balance'], 1000)
self.assertEqual(group1_lines['debit'], 0)
self.assertEqual(group1_lines['credit'], 0)
self.assertEqual(group1_lines['final_balance'], 1000)
# Add reversed move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -269,30 +267,42 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines()
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines()
trial_balance = res_data['trial_balance']
check_receivable_account = self.check_account_in_report(
self.account100.id, trial_balance)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.account200.id, trial_balance)
self.assertTrue(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].debit, 0)
self.assertEqual(lines['receivable'].credit, 1000)
self.assertEqual(lines['receivable'].final_balance, 0)
self.assertEqual(lines['income'].initial_balance, 0)
self.assertEqual(lines['income'].debit, 1000)
self.assertEqual(lines['income'].credit, 0)
self.assertEqual(lines['income'].final_balance, 1000)
self.assertEqual(lines['group1'].initial_balance, 1000)
self.assertEqual(lines['group1'].debit, 0)
self.assertEqual(lines['group1'].credit, 1000)
self.assertEqual(lines['group1'].final_balance, 0)
self.assertEqual(lines['group2'].initial_balance, 0)
self.assertEqual(lines['group2'].debit, 1000)
self.assertEqual(lines['group2'].credit, 0)
self.assertEqual(lines['group2'].final_balance, 1000)
account_receivable_lines = self._get_account_lines(
self.account100.id, trial_balance)
account_income_lines = self._get_account_lines(
self.account200.id, trial_balance)
group1_lines = self._get_group_lines(self.group1.id, trial_balance)
group2_lines = self._get_group_lines(self.group2.id, trial_balance)
self.assertEqual(account_receivable_lines['initial_balance'], 1000)
self.assertEqual(account_receivable_lines['debit'], 0)
self.assertEqual(account_receivable_lines['credit'], 1000)
self.assertEqual(account_receivable_lines['final_balance'], 0)
self.assertEqual(account_income_lines['initial_balance'], 0)
self.assertEqual(account_income_lines['debit'], 1000)
self.assertEqual(account_income_lines['credit'], 0)
self.assertEqual(account_income_lines['final_balance'], 1000)
self.assertEqual(group1_lines['initial_balance'], 1000)
self.assertEqual(group1_lines['debit'], 0)
self.assertEqual(group1_lines['credit'], 1000)
self.assertEqual(group1_lines['final_balance'], 0)
self.assertEqual(group2_lines['initial_balance'], 0)
self.assertEqual(group2_lines['debit'], 1000)
self.assertEqual(group2_lines['credit'], 0)
self.assertEqual(group2_lines['final_balance'], 1000)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
@ -305,37 +315,53 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines()
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines()
trial_balance = res_data['trial_balance']
check_receivable_account = self.check_account_in_report(
self.account100.id, trial_balance)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.account200.id, trial_balance)
self.assertTrue(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].debit, 0)
self.assertEqual(lines['receivable'].credit, 2000)
self.assertEqual(lines['receivable'].final_balance, -1000)
self.assertEqual(lines['income'].initial_balance, 0)
self.assertEqual(lines['income'].debit, 2000)
self.assertEqual(lines['income'].credit, 0)
self.assertEqual(lines['income'].final_balance, 2000)
self.assertEqual(lines['group1'].initial_balance, 1000)
self.assertEqual(lines['group1'].debit, 0)
self.assertEqual(lines['group1'].credit, 2000)
self.assertEqual(lines['group1'].final_balance, -1000)
self.assertEqual(lines['group2'].initial_balance, 0)
self.assertEqual(lines['group2'].debit, 2000)
self.assertEqual(lines['group2'].credit, 0)
self.assertEqual(lines['group2'].final_balance, 2000)
self.assertGreaterEqual(len(lines['group2'].compute_account_ids), 9)
account_receivable_lines = self._get_account_lines(
self.account100.id, trial_balance)
account_income_lines = self._get_account_lines(
self.account200.id, trial_balance)
group1_lines = self._get_group_lines(self.group1.id, trial_balance)
group2_lines = self._get_group_lines(self.group2.id, trial_balance)
self.assertEqual(account_receivable_lines['initial_balance'], 1000)
self.assertEqual(account_receivable_lines['debit'], 0)
self.assertEqual(account_receivable_lines['credit'], 2000)
self.assertEqual(account_receivable_lines['final_balance'], -1000)
self.assertEqual(account_income_lines['initial_balance'], 0)
self.assertEqual(account_income_lines['debit'], 2000)
self.assertEqual(account_income_lines['credit'], 0)
self.assertEqual(account_income_lines['final_balance'], 2000)
self.assertEqual(group1_lines['initial_balance'], 1000)
self.assertEqual(group1_lines['debit'], 0)
self.assertEqual(group1_lines['credit'], 2000)
self.assertEqual(group1_lines['final_balance'], -1000)
self.assertEqual(group2_lines['initial_balance'], 0)
self.assertEqual(group2_lines['debit'], 2000)
self.assertEqual(group2_lines['credit'], 0)
self.assertEqual(group2_lines['final_balance'], 2000)
def test_02_account_balance_hierarchy(self):
# Generate the general ledger line
lines = self._get_report_lines(hierarchy_on='relation')
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines(hierarchy_on='relation')
trial_balance = res_data['trial_balance']
check_receivable_account = self.check_account_in_report(
self.account100.id, trial_balance)
self.assertFalse(check_receivable_account)
check_income_account = self.check_account_in_report(
self.account200.id, trial_balance)
self.assertFalse(check_income_account)
# Add a move at the previous day of the first day of fiscal year
# to check the initial balance
@ -348,20 +374,29 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines(hierarchy_on='relation')
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines(hierarchy_on='relation')
trial_balance = res_data['trial_balance']
check_receivable_account = self.check_account_in_report(
self.account100.id, trial_balance)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.account200.id, trial_balance)
self.assertFalse(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].debit, 0)
self.assertEqual(lines['receivable'].credit, 0)
self.assertEqual(lines['receivable'].final_balance, 1000)
account_receivable_lines = self._get_account_lines(
self.account100.id, trial_balance)
group1_lines = self._get_group_lines(self.group1.id, trial_balance)
self.assertEqual(account_receivable_lines['initial_balance'], 1000)
self.assertEqual(account_receivable_lines['debit'], 0)
self.assertEqual(account_receivable_lines['credit'], 0)
self.assertEqual(account_receivable_lines['final_balance'], 1000)
self.assertEqual(lines['group1'].initial_balance, 1000)
self.assertEqual(lines['group1'].debit, 0)
self.assertEqual(lines['group1'].credit, 0)
self.assertEqual(lines['group1'].final_balance, 1000)
self.assertEqual(group1_lines['initial_balance'], 1000)
self.assertEqual(group1_lines['debit'], 0)
self.assertEqual(group1_lines['credit'], 0)
self.assertEqual(group1_lines['final_balance'], 1000)
# Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -375,31 +410,43 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines(hierarchy_on='relation')
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines(hierarchy_on='relation')
trial_balance = res_data['trial_balance']
check_receivable_account = self.check_account_in_report(
self.account100.id, trial_balance)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.account200.id, trial_balance)
self.assertTrue(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].debit, 0)
self.assertEqual(lines['receivable'].credit, 1000)
self.assertEqual(lines['receivable'].final_balance, 0)
self.assertEqual(lines['income'].initial_balance, 0)
self.assertEqual(lines['income'].debit, 1000)
self.assertEqual(lines['income'].credit, 0)
self.assertEqual(lines['income'].final_balance, 1000)
self.assertEqual(lines['group1'].initial_balance, 1000)
self.assertEqual(lines['group1'].debit, 0)
self.assertEqual(lines['group1'].credit, 1000)
self.assertEqual(lines['group1'].final_balance, 0)
self.assertEqual(lines['group2'].initial_balance, 0)
self.assertEqual(lines['group2'].debit, 2000)
self.assertEqual(lines['group2'].credit, 0)
self.assertEqual(lines['group2'].final_balance, 2000)
self.assertEqual(len(lines['group2'].compute_account_ids), 2)
account_receivable_lines = self._get_account_lines(
self.account100.id, trial_balance)
account_income_lines = self._get_account_lines(
self.account200.id, trial_balance)
group1_lines = self._get_group_lines(self.group1.id, trial_balance)
group2_lines = self._get_group_lines(self.group2.id, trial_balance)
self.assertEqual(account_receivable_lines['initial_balance'], 1000)
self.assertEqual(account_receivable_lines['debit'], 0)
self.assertEqual(account_receivable_lines['credit'], 1000)
self.assertEqual(account_receivable_lines['final_balance'], 0)
self.assertEqual(account_income_lines['initial_balance'], 0)
self.assertEqual(account_income_lines['debit'], 1000)
self.assertEqual(account_income_lines['credit'], 0)
self.assertEqual(account_income_lines['final_balance'], 1000)
self.assertEqual(group1_lines['initial_balance'], 1000)
self.assertEqual(group1_lines['debit'], 0)
self.assertEqual(group1_lines['credit'], 1000)
self.assertEqual(group1_lines['final_balance'], 0)
self.assertEqual(group2_lines['initial_balance'], 0)
self.assertEqual(group2_lines['debit'], 2000)
self.assertEqual(group2_lines['credit'], 0)
self.assertEqual(group2_lines['final_balance'], 2000)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
self._add_move(
@ -411,35 +458,50 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines(hierarchy_on='relation')
self.assertEqual(len(lines['receivable']), 1)
self.assertEqual(len(lines['income']), 1)
res_data = self._get_report_lines(hierarchy_on='relation')
trial_balance = res_data['trial_balance']
check_receivable_account = self.check_account_in_report(
self.account100.id, trial_balance)
self.assertTrue(check_receivable_account)
check_income_account = self.check_account_in_report(
self.account200.id, trial_balance)
self.assertTrue(check_income_account)
# Check the initial and final balance
self.assertEqual(lines['receivable'].initial_balance, 1000)
self.assertEqual(lines['receivable'].debit, 0)
self.assertEqual(lines['receivable'].credit, 2000)
self.assertEqual(lines['receivable'].final_balance, -1000)
self.assertEqual(lines['income'].initial_balance, 0)
self.assertEqual(lines['income'].debit, 2000)
self.assertEqual(lines['income'].credit, 0)
self.assertEqual(lines['income'].final_balance, 2000)
self.assertEqual(lines['group1'].initial_balance, 1000)
self.assertEqual(lines['group1'].debit, 0)
self.assertEqual(lines['group1'].credit, 2000)
self.assertEqual(lines['group1'].final_balance, -1000)
self.assertEqual(lines['group2'].initial_balance, 0)
self.assertEqual(lines['group2'].debit, 4000)
self.assertEqual(lines['group2'].credit, 0)
self.assertEqual(lines['group2'].final_balance, 4000)
account_receivable_lines = self._get_account_lines(
self.account100.id, trial_balance)
account_income_lines = self._get_account_lines(
self.account200.id, trial_balance)
group1_lines = self._get_group_lines(self.group1.id, trial_balance)
group2_lines = self._get_group_lines(self.group2.id, trial_balance)
self.assertEqual(account_receivable_lines['initial_balance'], 1000)
self.assertEqual(account_receivable_lines['debit'], 0)
self.assertEqual(account_receivable_lines['credit'], 2000)
self.assertEqual(account_receivable_lines['final_balance'], -1000)
self.assertEqual(account_income_lines['initial_balance'], 0)
self.assertEqual(account_income_lines['debit'], 2000)
self.assertEqual(account_income_lines['credit'], 0)
self.assertEqual(account_income_lines['final_balance'], 2000)
self.assertEqual(group1_lines['initial_balance'], 1000)
self.assertEqual(group1_lines['debit'], 0)
self.assertEqual(group1_lines['credit'], 2000)
self.assertEqual(group1_lines['final_balance'], -1000)
self.assertEqual(group2_lines['initial_balance'], 0)
self.assertEqual(group2_lines['debit'], 4000)
self.assertEqual(group2_lines['credit'], 0)
self.assertEqual(group2_lines['final_balance'], 4000)
def test_03_partner_balance(self):
# Generate the trial balance line
lines = self._get_report_lines(with_partners=True)
self.assertEqual(len(lines['partner_receivable']), 0)
res_data = self._get_report_lines(with_partners=True)
total_amount = res_data['total_amount']
check_partner_receivable = self.check_partner_in_report(
self.account100.id, self.partner.id, total_amount)
self.assertFalse(check_partner_receivable)
# Add a move at the previous day of the first day of fiscal year
# to check the initial balance
@ -452,14 +514,20 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines(with_partners=True)
self.assertEqual(len(lines['partner_receivable']), 1)
res_data = self._get_report_lines(with_partners=True)
total_amount = res_data['total_amount']
check_partner_receivable = self.check_partner_in_report(
self.account100.id, self.partner.id, total_amount)
self.assertTrue(check_partner_receivable)
# Check the initial and final balance
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
self.assertEqual(lines['partner_receivable'].debit, 0)
self.assertEqual(lines['partner_receivable'].credit, 0)
self.assertEqual(lines['partner_receivable'].final_balance, 1000)
partner_lines = self._get_partner_lines(
self.account100.id, self.partner.id, total_amount)
self.assertEqual(partner_lines['initial_balance'], 1000)
self.assertEqual(partner_lines['debit'], 0)
self.assertEqual(partner_lines['credit'], 0)
self.assertEqual(partner_lines['final_balance'], 1000)
# Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -473,14 +541,20 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines(with_partners=True)
self.assertEqual(len(lines['partner_receivable']), 1)
res_data = self._get_report_lines(with_partners=True)
total_amount = res_data['total_amount']
check_partner_receivable = self.check_partner_in_report(
self.account100.id, self.partner.id, total_amount)
self.assertTrue(check_partner_receivable)
# Check the initial and final balance
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
self.assertEqual(lines['partner_receivable'].debit, 0)
self.assertEqual(lines['partner_receivable'].credit, 1000)
self.assertEqual(lines['partner_receivable'].final_balance, 0)
partner_lines = self._get_partner_lines(
self.account100.id, self.partner.id, total_amount)
self.assertEqual(partner_lines['initial_balance'], 1000)
self.assertEqual(partner_lines['debit'], 0)
self.assertEqual(partner_lines['credit'], 1000)
self.assertEqual(partner_lines['final_balance'], 0)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
@ -493,14 +567,20 @@ class TestTrialBalanceReport(common.TransactionCase):
)
# Re Generate the trial balance line
lines = self._get_report_lines(with_partners=True)
self.assertEqual(len(lines['partner_receivable']), 1)
res_data = self._get_report_lines(with_partners=True)
total_amount = res_data['total_amount']
check_partner_receivable = self.check_partner_in_report(
self.account100.id, self.partner.id, total_amount)
self.assertTrue(check_partner_receivable)
# Check the initial and final balance
self.assertEqual(lines['partner_receivable'].initial_balance, 1000)
self.assertEqual(lines['partner_receivable'].debit, 0)
self.assertEqual(lines['partner_receivable'].credit, 2000)
self.assertEqual(lines['partner_receivable'].final_balance, -1000)
partner_lines = self._get_partner_lines(
self.account100.id, self.partner.id, total_amount)
self.assertEqual(partner_lines['initial_balance'], 1000)
self.assertEqual(partner_lines['debit'], 0)
self.assertEqual(partner_lines['credit'], 2000)
self.assertEqual(partner_lines['final_balance'], -1000)
def test_04_undistributed_pl(self):
# Add a P&L Move in the previous FY
@ -525,28 +605,33 @@ class TestTrialBalanceReport(common.TransactionCase):
move = self.env['account.move'].create(move_vals)
move.post()
# Generate the trial balance line
report_account_model = self.env['report_trial_balance_account']
company = self.env.ref('base.main_company')
trial_balance = self.env['report_trial_balance'].create({
trial_balance = self.env['trial.balance.report.wizard'].create({
'date_from': self.date_start,
'date_to': self.date_end,
'only_posted_moves': True,
'target_move': 'posted',
'hide_account_at_0': False,
'hierarchy_on': 'none',
'company_id': company.id,
'fy_start_date': self.fy_date_start,
})
trial_balance.compute_data_for_report()
unaffected_balance_lines = report_account_model.search([
('report_id', '=', trial_balance.id),
('account_id', '=', self.account110.id),
])
self.assertEqual(len(unaffected_balance_lines), 1)
self.assertEqual(unaffected_balance_lines[0].initial_balance, -1000)
self.assertEqual(unaffected_balance_lines[0].debit, 0)
self.assertEqual(unaffected_balance_lines[0].credit, 0)
self.assertEqual(unaffected_balance_lines[0].final_balance, -1000)
data = trial_balance._prepare_report_trial_balance()
res_data = self.env[
'report.account_financial_report.trial_balance']._get_report_values(
trial_balance, data)
trial_balance = res_data['trial_balance']
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, trial_balance)
self.assertTrue(check_unaffected_account)
unaffected_lines = self._get_account_lines(
self.unaffected_account.id, trial_balance)
self.assertEqual(unaffected_lines['initial_balance'], -1000)
self.assertEqual(unaffected_lines['debit'], 0)
self.assertEqual(unaffected_lines['credit'], 0)
self.assertEqual(unaffected_lines['final_balance'], -1000)
# Add a P&L Move to the current FY
move_name = 'current year pl move'
journal = self.env['account.journal'].search([], limit=1)
@ -569,27 +654,33 @@ class TestTrialBalanceReport(common.TransactionCase):
move = self.env['account.move'].create(move_vals)
move.post()
# Re Generate the trial balance line
trial_balance = self.env['report_trial_balance'].create({
trial_balance = self.env['trial.balance.report.wizard'].create({
'date_from': self.date_start,
'date_to': self.date_end,
'only_posted_moves': True,
'target_move': 'posted',
'hide_account_at_0': False,
'hierarchy_on': 'none',
'company_id': company.id,
'fy_start_date': self.fy_date_start,
})
trial_balance.compute_data_for_report()
unaffected_balance_lines = report_account_model.search([
('report_id', '=', trial_balance.id),
('account_id', '=', self.account110.id),
])
data = trial_balance._prepare_report_trial_balance()
res_data = self.env[
'report.account_financial_report.trial_balance']._get_report_values(
trial_balance, data)
trial_balance = res_data['trial_balance']
# The unaffected earnings account is not affected by a journal entry
# made to the P&L in the current fiscal year.
self.assertEqual(len(unaffected_balance_lines), 1)
self.assertEqual(unaffected_balance_lines[0].initial_balance, -1000)
self.assertEqual(unaffected_balance_lines[0].debit, 0)
self.assertEqual(unaffected_balance_lines[0].credit, 0)
self.assertEqual(unaffected_balance_lines[0].final_balance, -1000)
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, trial_balance)
self.assertTrue(check_unaffected_account)
unaffected_lines = self._get_account_lines(
self.unaffected_account.id, trial_balance)
self.assertEqual(unaffected_lines['initial_balance'], -1000)
self.assertEqual(unaffected_lines['debit'], 0)
self.assertEqual(unaffected_lines['credit'], 0)
self.assertEqual(unaffected_lines['final_balance'], -1000)
# Add a Move including Unaffected Earnings to the current FY
move_name = 'current year unaffected earnings move'
journal = self.env['account.journal'].search([], limit=1)
@ -612,32 +703,42 @@ class TestTrialBalanceReport(common.TransactionCase):
move = self.env['account.move'].create(move_vals)
move.post()
# Re Generate the trial balance line
trial_balance = self.env['report_trial_balance'].create({
trial_balance = self.env['trial.balance.report.wizard'].create({
'date_from': self.date_start,
'date_to': self.date_end,
'only_posted_moves': True,
'target_move': 'posted',
'hide_account_at_0': False,
'hierarchy_on': 'none',
'company_id': company.id,
'fy_start_date': self.fy_date_start,
})
trial_balance.compute_data_for_report()
data = trial_balance._prepare_report_trial_balance()
res_data = self.env[
'report.account_financial_report.trial_balance']._get_report_values(
trial_balance, data)
trial_balance = res_data['trial_balance']
# The unaffected earnings account affected by a journal entry
# made to the unaffected earnings in the current fiscal year.
unaffected_balance_lines = report_account_model.search([
('report_id', '=', trial_balance.id),
('account_id', '=', self.account110.id),
])
self.assertEqual(len(unaffected_balance_lines), 1)
self.assertEqual(unaffected_balance_lines[0].initial_balance, -1000)
self.assertEqual(unaffected_balance_lines[0].debit, 0)
self.assertEqual(unaffected_balance_lines[0].credit, 1000)
self.assertEqual(unaffected_balance_lines[0].final_balance, -2000)
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, trial_balance)
self.assertTrue(check_unaffected_account)
unaffected_lines = self._get_account_lines(
self.unaffected_account.id, trial_balance)
self.assertEqual(unaffected_lines['initial_balance'], -1000)
self.assertEqual(unaffected_lines['debit'], 0)
self.assertEqual(unaffected_lines['credit'], 1000)
self.assertEqual(unaffected_lines['final_balance'], -2000)
# The totals for the Trial Balance are zero
all_lines = report_account_model.search([
('report_id', '=', trial_balance.id),
])
self.assertEqual(sum(all_lines.mapped('initial_balance')), 0)
self.assertEqual(sum(all_lines.mapped('final_balance')), 0)
self.assertEqual(sum(all_lines.mapped('debit')),
sum(all_lines.mapped('credit')))
total_initial_balance = self._sum_all_accounts(trial_balance,
'initial_balance')
total_final_balance = self._sum_all_accounts(trial_balance,
'ending_balance')
total_debit = self._sum_all_accounts(trial_balance, 'debit')
total_credit = self._sum_all_accounts(trial_balance, 'credit')
self.assertEqual(total_initial_balance, 0)
self.assertEqual(total_final_balance, 0)
self.assertEqual(total_debit, total_credit)

243
account_financial_report/tests/test_vat_report.py

@ -1,47 +1,10 @@
# Copyright 2018 Forest and Biomass Romania
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import time
from datetime import date
from odoo.tests import common
from . import abstract_test_tax_report
class TestVAT(abstract_test_tax_report.AbstractTest):
"""
Technical tests for VAT Report.
"""
def _getReportModel(self):
return self.env['report_vat_report']
def _getQwebReportName(self):
return 'account_financial_report.report_vat_report_qweb'
def _getXlsxReportName(self):
return 'a_f_r.report_vat_report_xlsx'
def _getXlsxReportActionName(self):
return 'account_financial_report.action_report_vat_report_xlsx'
def _getReportTitle(self):
return 'Odoo'
def _getBaseFilters(self):
return {
'date_from': date(date.today().year, 1, 1),
'date_to': date(date.today().year, 12, 31),
'company_id': self.env.user.company_id.id,
}
def _getAdditionalFiltersToBeTested(self):
return [
{'based_on': 'taxtags'},
{'based_on': 'taxgroups'},
{'tax_details': True},
{'based_on': 'taxtags', 'tax_details': True},
{'based_on': 'taxgroups', 'tax_details': True},
]
class TestVATReport(common.TransactionCase):
@ -155,106 +118,142 @@ class TestVATReport(common.TransactionCase):
self.cbinvoice.compute_taxes()
self.cbinvoice.action_invoice_open()
def _get_report_lines(self):
self.cbinvoice.pay_and_reconcile(
self.bank_journal.id, 300, date(
date.today().year, date.today().month, 10))
vat_report = self.env['report_vat_report'].create({
def _get_report_lines(self, taxgroups=False):
based_on = 'taxtags'
if taxgroups:
based_on = 'taxgroups'
vat_report = self.env['vat.report.wizard'].create({
'date_from': self.date_from,
'date_to': self.date_to,
'company_id': self.company.id,
'based_on': 'taxtags',
'based_on': based_on,
'tax_detail': True,
})
vat_report.compute_data_for_report()
lines = {}
vat_taxtag_model = self.env['report_vat_report_taxtag']
lines['tag_01'] = vat_taxtag_model.search([
('report_id', '=', vat_report.id),
('taxtag_id', '=', self.tax_tag_01.id),
])
lines['tag_02'] = vat_taxtag_model.search([
('report_id', '=', vat_report.id),
('taxtag_id', '=', self.tax_tag_02.id),
])
lines['tag_03'] = vat_taxtag_model.search([
('report_id', '=', vat_report.id),
('taxtag_id', '=', self.tax_tag_03.id),
])
vat_tax_model = self.env['report_vat_report_tax']
lines['tax_10'] = vat_tax_model.search([
('report_tax_id', '=', lines['tag_02'].id),
('tax_id', '=', self.tax_10.id),
])
lines['tax_20'] = vat_tax_model.search([
('report_tax_id', '=', lines['tag_02'].id),
('tax_id', '=', self.tax_20.id),
])
vat_report['based_on'] = 'taxgroups'
vat_report.compute_data_for_report()
lines['group_10'] = vat_taxtag_model.search([
('report_id', '=', vat_report.id),
('taxgroup_id', '=', self.tax_group_10.id),
])
lines['group_20'] = vat_taxtag_model.search([
('report_id', '=', vat_report.id),
('taxgroup_id', '=', self.tax_group_20.id),
])
vat_tax_model = self.env['report_vat_report_tax']
lines['tax_group_10'] = vat_tax_model.search([
('report_tax_id', '=', lines['group_10'].id),
('tax_id', '=', self.tax_10.id),
])
lines['tax_group_20'] = vat_tax_model.search([
('report_tax_id', '=', lines['group_20'].id),
('tax_id', '=', self.tax_20.id),
])
return lines
data = vat_report._prepare_vat_report()
res_data = self.env[
'report.account_financial_report.vat_report'
]._get_report_values(vat_report, data)
return res_data
def check_tag_or_group_in_report(self, tag_or_group_name, vat_report):
tag_or_group_in_report = False
for tag_or_group in vat_report:
if tag_or_group['name'] == tag_or_group_name:
tag_or_group_in_report = True
break
return tag_or_group_in_report
def check_tax_in_report(self, tax_name, vat_report):
tax_in_report = False
for tag_or_group in vat_report:
if tag_or_group['taxes']:
for tax in tag_or_group['taxes']:
if tax['name'] == tax_name:
tax_in_report = True
return tax_in_report
def _get_tag_or_group_line(self, tag_or_group_name, vat_report):
tag_or_group_net = False
tag_or_group_tax = False
for tag_or_group in vat_report:
if tag_or_group['name'] == tag_or_group_name:
tag_or_group_net = tag_or_group['net']
tag_or_group_tax = tag_or_group['tax']
return tag_or_group_net, tag_or_group_tax
def _get_tax_line(self, tax_name, vat_report):
tax_net = False
tax_tax = False
for tag_or_group in vat_report:
if tag_or_group['taxes']:
for tax in tag_or_group['taxes']:
if tax['name'] == tax_name:
tax_net = tax['net']
tax_tax = tax['tax']
return tax_net, tax_tax
def test_01_compute(self):
# Generate the vat lines
lines = self._get_report_lines()
res_data = self._get_report_lines()
vat_report = res_data['vat_report']
# Check report based on taxtags
self.assertEqual(len(lines['tag_01']), 1)
self.assertEqual(len(lines['tag_02']), 1)
self.assertEqual(len(lines['tag_03']), 1)
self.assertEqual(len(lines['tax_10']), 1)
self.assertEqual(len(lines['tax_20']), 1)
self.assertEqual(lines['tag_01'].net, 100)
self.assertEqual(lines['tag_01'].tax, 10)
self.assertEqual(lines['tag_02'].net, 350)
self.assertEqual(lines['tag_02'].tax, 60)
self.assertEqual(lines['tag_03'].net, 250)
self.assertEqual(lines['tag_03'].tax, 50)
self.assertEqual(lines['tax_10'].net, 100)
self.assertEqual(lines['tax_10'].tax, 10)
self.assertEqual(lines['tax_20'].net, 250)
self.assertEqual(lines['tax_20'].tax, 50)
check_tax_tag_01 = self.check_tag_or_group_in_report(
self.tax_tag_01.name, vat_report)
self.assertTrue(check_tax_tag_01)
check_tax_tag_02 = self.check_tag_or_group_in_report(
self.tax_tag_02.name, vat_report)
self.assertTrue(check_tax_tag_02)
check_tax_tag_03 = self.check_tag_or_group_in_report(
self.tax_tag_03.name, vat_report)
self.assertTrue(check_tax_tag_03)
check_tax_10 = self.check_tax_in_report(
self.tax_10.name, vat_report)
self.assertTrue(check_tax_10)
check_tax_20 = self.check_tax_in_report(
self.tax_20.name, vat_report)
self.assertTrue(check_tax_20)
tag_01_net, tag_01_tax = self._get_tag_or_group_line(
self.tax_tag_01.name, vat_report)
tag_02_net, tag_02_tax = self._get_tag_or_group_line(
self.tax_tag_02.name, vat_report)
tag_03_net, tag_03_tax = self._get_tag_or_group_line(
self.tax_tag_03.name, vat_report)
tax_10_net, tax_10_tax = self._get_tax_line(
self.tax_10.name, vat_report)
tax_20_net, tax_20_tax = self._get_tax_line(
self.tax_20.name, vat_report)
self.assertEqual(tag_01_net, 100)
self.assertEqual(tag_01_tax, 10)
self.assertEqual(tag_02_net, 350)
self.assertEqual(tag_02_tax, 60)
self.assertEqual(tag_03_net, 250)
self.assertEqual(tag_03_tax, 50)
self.assertEqual(tax_10_net, 100)
self.assertEqual(tax_10_tax, 10)
self.assertEqual(tax_20_net, 250)
self.assertEqual(tax_20_tax, 50)
# Check report based on taxgroups
self.assertEqual(len(lines['group_10']), 1)
self.assertEqual(len(lines['group_20']), 1)
self.assertEqual(len(lines['tax_group_10']), 1)
self.assertEqual(len(lines['tax_group_20']), 1)
self.assertEqual(lines['group_10'].net, 100)
self.assertEqual(lines['group_10'].tax, 10)
self.assertEqual(lines['group_20'].net, 250)
self.assertEqual(lines['group_20'].tax, 50)
self.assertEqual(lines['tax_group_10'].net, 100)
self.assertEqual(lines['tax_group_10'].tax, 10)
self.assertEqual(lines['tax_group_20'].net, 250)
self.assertEqual(lines['tax_group_20'].tax, 50)
res_data = self._get_report_lines(taxgroups=True)
vat_report = res_data['vat_report']
def test_get_report_html(self):
vat_report = self.env['report_vat_report'].create({
'date_from': self.date_from,
'date_to': self.date_to,
'company_id': self.company.id,
'tax_detail': True,
})
vat_report.compute_data_for_report()
vat_report.get_html(given_context={})
check_group_10 = self.check_tag_or_group_in_report(
self.tax_group_10.name, vat_report)
self.assertTrue(check_group_10)
check_group_20 = self.check_tag_or_group_in_report(
self.tax_group_20.name, vat_report)
self.assertTrue(check_group_20)
check_tax_10 = self.check_tax_in_report(
self.tax_10.name, vat_report)
self.assertTrue(check_tax_10)
check_tax_20 = self.check_tax_in_report(
self.tax_20.name, vat_report)
self.assertTrue(check_tax_20)
group_10_net, group_10_tax = self._get_tag_or_group_line(
self.tax_group_10.name, vat_report)
group_20_net, group_20_tax = self._get_tag_or_group_line(
self.tax_group_20.name, vat_report)
tax_10_net, tax_10_tax = self._get_tax_line(
self.tax_10.name, vat_report)
tax_20_net, tax_20_tax = self._get_tax_line(
self.tax_20.name, vat_report)
self.assertEqual(group_10_net, 100)
self.assertEqual(group_10_tax, 10)
self.assertEqual(group_20_net, 250)
self.assertEqual(group_20_tax, 50)
self.assertEqual(tax_10_net, 100)
self.assertEqual(tax_10_tax, 10)
self.assertEqual(tax_20_net, 250)
self.assertEqual(tax_20_tax, 50)
def test_wizard_date_range(self):
vat_wizard = self.env['vat.report.wizard']

20
account_financial_report/view/report_template.xml

@ -6,7 +6,7 @@
<xpath expr="." position="inside">
<link href="/account_financial_report/static/src/css/report.css" rel="stylesheet"/>
<script type="text/javascript"
src="/account_financial_report/static/src/js/account_financial_report_backend.js"/>
src="/account_financial_report/static/src/js/account_financial_report_backend.js"/>
<script type="text/javascript"
src="/account_financial_report/static/src/js/account_financial_report_widgets.js"/>
</xpath>
@ -22,37 +22,37 @@
<record id="action_report_general_ledger" model="ir.actions.client">
<field name="name">General Ledger</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'active_model': 'report_general_ledger'}" />
<field name="context" eval="{'model': 'report.account_financial_report.general_ledger'}" />
</record>
<record id="action_report_journal_ledger" model="ir.actions.client">
<field name="name">Journal</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'active_model': 'report_journal_ledger'}" />
<field name="context" eval="{'model': 'report.account_financial_report.journal_ledger'}" />
</record>
<record id="action_report_open_items" model="ir.actions.client">
<field name="name">Open Items</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'active_model': 'report_open_items'}" />
<field name="name">Open Items</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'model': 'report.account_financial_report.open_items'}" />
</record>
<record id="action_report_trial_balance" model="ir.actions.client">
<field name="name">Trial Balance</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'active_model': 'report_trial_balance'}" />
<field name="context" eval="{'model': 'report.account_financial_report.trial_balance'}" />
</record>
<record id="action_report_aged_partner_balance" model="ir.actions.client">
<field name="name">Aged Partner Balance</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'active_model': 'report_aged_partner_balance'}" />
<field name="context" eval="{'model': 'report.account_financial_report.aged_partner_balance'}" />
</record>
<record id="action_report_vat_report" model="ir.actions.client">
<field name="name">VAT Report</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'active_model': 'report_vat_report'}" />
<field name="context" eval="{'model': 'report.account_financial_report.vat_report'}" />
</record>
</odoo>

49
account_financial_report/wizard/aged_partner_balance_wizard.py

@ -4,14 +4,12 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
class AgedPartnerBalanceWizard(models.TransientModel):
"""Aged partner balance report wizard."""
_name = 'aged.partner.balance.wizard'
_name = 'aged.partner.balance.report.wizard'
_description = 'Aged Partner Balance Wizard'
_inherit = 'account_financial_report_abstract_wizard'
@ -66,35 +64,36 @@ class AgedPartnerBalanceWizard(models.TransientModel):
@api.onchange('receivable_accounts_only', 'payable_accounts_only')
def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change."""
domain = [('company_id', '=', self.company_id.id)]
if self.receivable_accounts_only or self.payable_accounts_only:
domain = [('company_id', '=', self.company_id.id)]
if self.receivable_accounts_only and self.payable_accounts_only:
domain += [('internal_type', 'in', ('receivable', 'payable'))]
elif self.receivable_accounts_only:
domain += [('internal_type', '=', 'receivable')]
elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')]
self.account_ids = self.env['account.account'].search(domain)
elif not self.receivable_accounts_only and not self.payable_accounts_only:
domain += [('reconcile', '=', True)]
self.account_ids = self.env['account.account'].search(domain)
@api.multi
def _print_report(self, report_type):
self.ensure_one()
data = self._prepare_report_aged_partner_balance()
if report_type == 'xlsx':
report_name = 'a_f_r.report_aged_partner_balance_xlsx'
else:
self.account_ids = None
report_name = 'account_financial_report.aged_partner_balance'
return self.env['ir.actions.report'].search(
[('report_name', '=', report_name),
('report_type', '=', report_type)], limit=1).report_action(
self, data=data)
@api.multi
def button_export_html(self):
self.ensure_one()
action = self.env.ref(
'account_financial_report.action_report_aged_partner_balance')
vals = action.read()[0]
context1 = vals.get('context', {})
if isinstance(context1, pycompat.string_types):
context1 = safe_eval(context1)
model = self.env['report_aged_partner_balance']
report = model.create(self._prepare_report_aged_partner_balance())
report.compute_data_for_report()
context1['active_id'] = report.id
context1['active_ids'] = report.ids
vals['context'] = context1
return vals
report_type = 'qweb-html'
return self._export(report_type)
@api.multi
def button_export_pdf(self):
@ -111,17 +110,15 @@ class AgedPartnerBalanceWizard(models.TransientModel):
def _prepare_report_aged_partner_balance(self):
self.ensure_one()
return {
'wizard_id': self.id,
'date_at': self.date_at,
'only_posted_moves': self.target_move == 'posted',
'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_partner_ids': [(6, 0, self.partner_ids.ids)],
'account_ids': self.account_ids.ids,
'partner_ids': self.partner_ids.ids,
'show_move_line_details': self.show_move_line_details,
}
def _export(self, report_type):
"""Default export is PDF."""
model = self.env['report_aged_partner_balance']
report = model.create(self._prepare_report_aged_partner_balance())
report.compute_data_for_report()
return report.print_report(report_type)
return self._print_report(report_type)

4
account_financial_report/wizard/aged_partner_balance_wizard_view.xml

@ -4,7 +4,7 @@
<!-- AGED PARTNER BALANCE -->
<record id="aged_partner_balance_wizard" model="ir.ui.view">
<field name="name">Aged Partner Balance</field>
<field name="model">aged.partner.balance.wizard</field>
<field name="model">aged.partner.balance.report.wizard</field>
<field name="arch" type="xml">
<form>
<group name="main_info">
@ -50,7 +50,7 @@
<act_window id="action_aged_partner_balance_wizard"
name="Aged Partner Balance"
res_model="aged.partner.balance.wizard"
res_model="aged.partner.balance.report.wizard"
view_type="form"
view_mode="form"
view_id="aged_partner_balance_wizard"

71
account_financial_report/wizard/general_ledger_wizard.py

@ -8,8 +8,6 @@
from odoo import api, fields, models, _
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
from odoo.exceptions import ValidationError
import time
@ -203,22 +201,42 @@ class GeneralLedgerReportWizard(models.TransientModel):
else:
self.receivable_accounts_only = self.payable_accounts_only = False
@api.multi
@api.depends('company_id')
def _compute_unaffected_earnings_account(self):
account_type = self.env.ref('account.data_unaffected_earnings')
for record in self:
record.unaffected_earnings_account = self.env[
'account.account'].search(
[
('user_type_id', '=', account_type.id),
('company_id', '=', record.company_id.id)
])
unaffected_earnings_account = fields.Many2one(
comodel_name='account.account',
compute='_compute_unaffected_earnings_account',
store=True
)
@api.multi
def _print_report(self, report_type):
self.ensure_one()
data = self._prepare_report_general_ledger()
if report_type == 'xlsx':
report_name = 'a_f_r.report_general_ledger_xlsx'
else:
report_name = 'account_financial_report.general_ledger'
return self.env['ir.actions.report'].search(
[('report_name', '=', report_name),
('report_type', '=', report_type)], limit=1).report_action(
self, data=data)
@api.multi
def button_export_html(self):
self.ensure_one()
action = self.env.ref(
'account_financial_report.action_report_general_ledger')
action_data = action.read()[0]
context1 = action_data.get('context', {})
if isinstance(context1, pycompat.string_types):
context1 = safe_eval(context1)
model = self.env['report_general_ledger']
report = model.create(self._prepare_report_general_ledger())
report.compute_data_for_report()
context1['active_id'] = report.id
context1['active_ids'] = report.ids
action_data['context'] = context1
return action_data
report_type = 'qweb-html'
return self._export(report_type)
@api.multi
def button_export_pdf(self):
@ -235,6 +253,7 @@ class GeneralLedgerReportWizard(models.TransientModel):
def _prepare_report_general_ledger(self):
self.ensure_one()
return {
'wizard_id': self.id,
'date_from': self.date_from,
'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted',
@ -242,18 +261,22 @@ class GeneralLedgerReportWizard(models.TransientModel):
'foreign_currency': self.foreign_currency,
'show_analytic_tags': self.show_analytic_tags,
'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_partner_ids': [(6, 0, self.partner_ids.ids)],
'filter_cost_center_ids': [(6, 0, self.cost_center_ids.ids)],
'filter_analytic_tag_ids': [(6, 0, self.analytic_tag_ids.ids)],
'filter_journal_ids': [(6, 0, self.account_journal_ids.ids)],
'account_ids': self.account_ids.ids,
'partner_ids': self.partner_ids.ids,
'cost_center_ids': self.cost_center_ids.ids,
'analytic_tag_ids': self.analytic_tag_ids.ids,
'journal_ids': self.account_journal_ids.ids,
'centralize': self.centralize,
'fy_start_date': self.fy_start_date,
'unaffected_earnings_account': self.unaffected_earnings_account.id,
}
def _export(self, report_type):
"""Default export is PDF."""
model = self.env['report_general_ledger']
report = model.create(self._prepare_report_general_ledger())
report.compute_data_for_report()
return report.print_report(report_type)
return self._print_report(report_type)
def _get_atr_from_dict(self, obj_id, data, key):
try:
return data[obj_id][key]
except KeyError:
return data[str(obj_id)][key]

79
account_financial_report/wizard/journal_ledger_wizard.py

@ -2,8 +2,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
class JournalLedgerReportWizard(models.TransientModel):
@ -102,26 +100,27 @@ class JournalLedgerReportWizard(models.TransientModel):
('company_id', '=', self.company_id.id)]
return res
@api.multi
def _print_report(self, report_type):
self.ensure_one()
data = self._prepare_report_journal_ledger()
if report_type == 'xlsx':
report_name = 'a_f_r.report_journal_ledger_xlsx'
else:
report_name = 'account_financial_report.journal_ledger'
return self.env['ir.actions.report'].search(
[('report_name', '=', report_name),
('report_type', '=', report_type)], limit=1).report_action(
self, data=data)
@api.multi
def button_export_html(self):
self.ensure_one()
action = self.env.ref(
'account_financial_report.action_report_journal_ledger')
vals = action.read()[0]
context1 = vals.get('context', {})
if isinstance(context1, pycompat.string_types):
context1 = safe_eval(context1)
model = self.env['report_journal_ledger']
report = model.create(self._prepare_report_journal_ledger())
report.compute_data_for_report()
context1['active_id'] = report.id
context1['active_ids'] = report.ids
vals['context'] = context1
return vals
report_type = 'qweb-html'
return self._export(report_type)
@api.multi
def button_export_pdf(self):
self.ensure_one()
report_type = 'qweb-pdf'
return self._export(report_type)
@ -140,12 +139,13 @@ class JournalLedgerReportWizard(models.TransientModel):
journals = self.env['account.journal'].search(
[('company_id', '=', self.company_id.id)])
return {
'wizard_id': self.id,
'date_from': self.date_from,
'date_to': self.date_to,
'move_target': self.move_target,
'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id,
'journal_ids': [(6, 0, journals.ids)],
'journal_ids': journals.ids,
'sort_option': self.sort_option,
'group_option': self.group_option,
'with_account_name': self.with_account_name,
@ -154,7 +154,44 @@ class JournalLedgerReportWizard(models.TransientModel):
def _export(self, report_type):
"""Default export is PDF."""
self.ensure_one()
model = self.env['report_journal_ledger']
report = model.create(self._prepare_report_journal_ledger())
report.compute_data_for_report()
return report.print_report(report_type)
return self._print_report(report_type)
@api.model
def _get_ml_tax_description(
self, move_line_data, tax_line_data, move_line_taxes_data):
taxes_description = ''
if move_line_data['tax_line_id']:
taxes_description = tax_line_data['description'] or \
tax_line_data['name']
elif move_line_taxes_data:
tax_names = []
for tax_key in move_line_taxes_data:
tax = move_line_taxes_data[tax_key]
tax_names.append(
tax['description'] or tax['name'])
taxes_description = ','.join(tax_names)
return taxes_description
@api.model
def _get_partner_name(self, partner_id, partner_data):
if str(partner_id) in partner_data.keys():
return partner_data[str(partner_id)]['name']
else:
return ''
@api.model
def _get_atr_from_dict(self, obj_id, data, key):
try:
return data[obj_id][key]
except KeyError:
return data[str(obj_id)][key]
@api.model
def _get_data_from_dict(self, obj_id, data):
if data:
if isinstance(list(data.keys())[0], int):
return data.get(obj_id, False)
else:
return data.get(obj_id(obj_id), False)
else:
return False

53
account_financial_report/wizard/open_items_wizard.py

@ -4,8 +4,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
class OpenItemsReportWizard(models.TransientModel):
@ -23,6 +21,7 @@ class OpenItemsReportWizard(models.TransientModel):
)
date_at = fields.Date(required=True,
default=fields.Date.context_today)
date_from = fields.Date(string='Date From')
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')],
string='Target Moves',
@ -84,35 +83,36 @@ class OpenItemsReportWizard(models.TransientModel):
@api.onchange('receivable_accounts_only', 'payable_accounts_only')
def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change."""
domain = [('company_id', '=', self.company_id.id)]
if self.receivable_accounts_only or self.payable_accounts_only:
domain = [('company_id', '=', self.company_id.id)]
if self.receivable_accounts_only and self.payable_accounts_only:
domain += [('internal_type', 'in', ('receivable', 'payable'))]
elif self.receivable_accounts_only:
domain += [('internal_type', '=', 'receivable')]
elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')]
self.account_ids = self.env['account.account'].search(domain)
elif not self.receivable_accounts_only and not self.payable_accounts_only:
domain += [('reconcile', '=', True)]
self.account_ids = self.env['account.account'].search(domain)
@api.multi
def _print_report(self, report_type):
self.ensure_one()
data = self._prepare_report_open_items()
if report_type == 'xlsx':
report_name = 'a_f_r.report_open_items_xlsx'
else:
self.account_ids = None
report_name = 'account_financial_report.open_items'
return self.env['ir.actions.report'].search(
[('report_name', '=', report_name),
('report_type', '=', report_type)], limit=1).report_action(
self, data=data)
@api.multi
def button_export_html(self):
self.ensure_one()
action = self.env.ref(
'account_financial_report.action_report_open_items')
vals = action.read()[0]
context1 = vals.get('context', {})
if isinstance(context1, pycompat.string_types):
context1 = safe_eval(context1)
model = self.env['report_open_items']
report = model.create(self._prepare_report_open_items())
report.compute_data_for_report()
context1['active_id'] = report.id
context1['active_ids'] = report.ids
vals['context'] = context1
return vals
report_type = 'qweb-html'
return self._export(report_type)
@api.multi
def button_export_pdf(self):
@ -129,18 +129,17 @@ class OpenItemsReportWizard(models.TransientModel):
def _prepare_report_open_items(self):
self.ensure_one()
return {
'date_at': self.date_at,
'wizard_id': self.id,
'date_at': fields.Date.to_string(self.date_at),
'date_from': self.date_from or False,
'only_posted_moves': self.target_move == 'posted',
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_partner_ids': [(6, 0, self.partner_ids.ids)],
'target_move': self.target_move,
'account_ids': self.account_ids.ids,
'partner_ids': self.partner_ids.ids or [],
}
def _export(self, report_type):
"""Default export is PDF."""
model = self.env['report_open_items']
report = model.create(self._prepare_report_open_items())
report.compute_data_for_report()
return report.print_report(report_type)
return self._print_report(report_type)

1
account_financial_report/wizard/open_items_wizard_view.xml

@ -13,6 +13,7 @@
<group name="filters">
<group name="date_range">
<field name="date_at"/>
<field name="date_from"/>
</group>
<group name="other_filters">
<field name="target_move" widget="radio"/>

67
account_financial_report/wizard/trial_balance_wizard.py

@ -5,8 +5,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models, _
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
from odoo.exceptions import UserError, ValidationError
@ -41,7 +39,7 @@ class TrialBalanceReportWizard(models.TransientModel):
('none', 'No hierarchy')],
string='Hierarchy On',
required=True,
default='computed',
default='none',
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
@ -183,25 +181,45 @@ class TrialBalanceReportWizard(models.TransientModel):
if self.show_partner_details:
self.receivable_accounts_only = self.payable_accounts_only = True
else:
self.receivable_accounts_only = self.payable_accounts_only = False
self.receivable_accounts_only = self.\
payable_accounts_only = False
@api.multi
@api.depends('company_id')
def _compute_unaffected_earnings_account(self):
account_type = self.env.ref('account.data_unaffected_earnings')
for record in self:
record.unaffected_earnings_account = self.env[
'account.account'].search(
[
('user_type_id', '=', account_type.id),
('company_id', '=', record.company_id.id)
])
unaffected_earnings_account = fields.Many2one(
comodel_name='account.account',
compute='_compute_unaffected_earnings_account',
store=True
)
@api.multi
def _print_report(self, report_type):
self.ensure_one()
data = self._prepare_report_trial_balance()
if report_type == 'xlsx':
report_name = 'a_f_r.report_trial_balance_xlsx'
else:
report_name = 'account_financial_report.trial_balance'
return self.env['ir.actions.report'].search(
[('report_name', '=', report_name),
('report_type', '=', report_type)], limit=1).report_action(
self, data=data)
@api.multi
def button_export_html(self):
self.ensure_one()
action = self.env.ref(
'account_financial_report.action_report_trial_balance')
vals = action.read()[0]
context1 = vals.get('context', {})
if isinstance(context1, pycompat.string_types):
context1 = safe_eval(context1)
model = self.env['report_trial_balance']
report = model.create(self._prepare_report_trial_balance())
report.compute_data_for_report()
context1['active_id'] = report.id
context1['active_ids'] = report.ids
vals['context'] = context1
return vals
report_type = 'qweb-html'
return self._export(report_type)
@api.multi
def button_export_pdf(self):
@ -218,26 +236,25 @@ class TrialBalanceReportWizard(models.TransientModel):
def _prepare_report_trial_balance(self):
self.ensure_one()
return {
'wizard_id': self.id,
'date_from': self.date_from,
'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted',
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_partner_ids': [(6, 0, self.partner_ids.ids)],
'filter_journal_ids': [(6, 0, self.journal_ids.ids)],
'account_ids': self.account_ids.ids or [],
'partner_ids': self.partner_ids.ids or [],
'journal_ids': self.journal_ids.ids or [],
'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,
'hide_parent_hierarchy_level': self.hide_parent_hierarchy_level,
'show_partner_details': self.show_partner_details,
'unaffected_earnings_account': self.unaffected_earnings_account.id,
}
def _export(self, report_type):
"""Default export is PDF."""
model = self.env['report_trial_balance']
report = model.create(self._prepare_report_trial_balance())
report.compute_data_for_report()
return report.print_report(report_type)
return self._print_report(report_type)

2
account_financial_report/wizard/trial_balance_wizard_view.xml

@ -23,7 +23,7 @@
<field name="hide_account_at_0"/>
<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="limit_hierarchy_level" attrs="{'invisible':['|', ('hierarchy_on','in',['none', 'computed']),('show_partner_details','=',True)]}"/>
<field name="show_hierarchy_level" attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"/>
<field name="hide_parent_hierarchy_level" attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"/>
<field name="foreign_currency"/>

36
account_financial_report/wizard/vat_report_wizard.py

@ -2,8 +2,6 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models, _
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
from odoo.exceptions import ValidationError
@ -62,22 +60,24 @@ class VATReportWizard(models.TransientModel):
_('The Company in the Vat Report Wizard and in '
'Date Range must be the same.'))
@api.multi
def _print_report(self, report_type):
self.ensure_one()
data = self._prepare_vat_report()
if report_type == 'xlsx':
report_name = 'a_f_r.report_vat_report_xlsx'
else:
report_name = 'account_financial_report.vat_report'
return self.env['ir.actions.report'].search(
[('report_name', '=', report_name),
('report_type', '=', report_type)], limit=1).report_action(
self, data=data)
@api.multi
def button_export_html(self):
self.ensure_one()
action = self.env.ref(
'account_financial_report.action_report_vat_report')
vals = action.read()[0]
context1 = vals.get('context', {})
if isinstance(context1, pycompat.string_types):
context1 = safe_eval(context1)
model = self.env['report_vat_report']
report = model.create(self._prepare_vat_report())
report.compute_data_for_report()
context1['active_id'] = report.id
context1['active_ids'] = report.ids
vals['context'] = context1
return vals
report_type = 'qweb-html'
return self._export(report_type)
@api.multi
def button_export_pdf(self):
@ -94,6 +94,7 @@ class VATReportWizard(models.TransientModel):
def _prepare_vat_report(self):
self.ensure_one()
return {
'wizard_id': self.id,
'company_id': self.company_id.id,
'date_from': self.date_from,
'date_to': self.date_to,
@ -103,7 +104,4 @@ class VATReportWizard(models.TransientModel):
def _export(self, report_type):
"""Default export is PDF."""
model = self.env['report_vat_report']
report = model.create(self._prepare_vat_report())
report.compute_data_for_report()
return report.print_report(report_type)
return self._print_report(report_type)
Loading…
Cancel
Save