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

22
account_financial_report/models/account_group.py

@ -23,6 +23,28 @@ class AccountGroup(models.Model):
'account.account', 'account.account',
compute='_compute_group_accounts', compute='_compute_group_accounts',
string="Compute accounts", store=True) 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.multi
@api.depends('parent_id', 'parent_id.level') @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> * Yannick Vaucher <yannick.vaucher@camptocamp.com>
* Simone Orsi <simone.orsi@abstract.com> * Simone Orsi <simone.orsi@abstract.com>
* Leonardo Pistone <leonardo.pistone@camptocamp.com> * Leonardo Pistone <leonardo.pistone@camptocamp.com>
@ -14,7 +14,8 @@
* Akim Juillerat <akim.juillerat@camptocamp.com> * Akim Juillerat <akim.juillerat@camptocamp.com>
* Alexis de Lattre <alexis@via.ecp.fr> * Alexis de Lattre <alexis@via.ecp.fr>
* Mihai Fekete <feketemihai@gmail.com> * 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>`__: * `Tecnativa <https://www.tecnativa.com>`__:
* Pedro M. Baeza * Pedro M. Baeza

1
account_financial_report/report/__init__.py

@ -3,7 +3,6 @@
# © 2016 Julien Coux (Camptocamp) # © 2016 Julien Coux (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-
from . import abstract_report
from . import abstract_report_xlsx from . import abstract_report_xlsx
from . import aged_partner_balance from . import aged_partner_balance
from . import aged_partner_balance_xlsx 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 # Author: Julien Coux
# Copyright 2016 Camptocamp SA # Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields
import datetime
from odoo import models
class AbstractReportXslx(models.AbstractModel): class AbstractReportXslx(models.AbstractModel):
@ -42,7 +40,7 @@ class AbstractReportXslx(models.AbstractModel):
self._define_formats(workbook) 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() report_footer = self._get_report_footer()
filters = self._get_report_filters(report) filters = self._get_report_filters(report)
self.columns = self._get_report_columns(report) self.columns = self._get_report_columns(report)
@ -55,14 +53,13 @@ class AbstractReportXslx(models.AbstractModel):
self._write_filters(filters) self._write_filters(filters)
self._generate_report_content(workbook, report)
self._generate_report_content(workbook, report, data)
self._write_report_footer(report_footer) self._write_report_footer(report_footer)
def _define_formats(self, workbook): def _define_formats(self, workbook):
""" Add cell formats to current workbook. """ Add cell formats to current workbook.
Those formats can be used on all cell. Those formats can be used on all cell.
Available formats are : Available formats are :
* format_bold * format_bold
* format_right * format_right
@ -189,8 +186,6 @@ class AbstractReportXslx(models.AbstractModel):
""" """
for col_pos, column in self.columns.items(): for col_pos, column in self.columns.items():
value = getattr(line_object, column['field']) value = getattr(line_object, column['field'])
if isinstance(value, datetime.date):
value = fields.Date.to_string(value)
cell_type = column.get('type', 'string') cell_type = column.get('type', 'string')
if cell_type == 'many2one': if cell_type == 'many2one':
self.sheet.write_string( self.sheet.write_string(
@ -219,10 +214,49 @@ class AbstractReportXslx(models.AbstractModel):
) )
self.row_pos += 1 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): def write_initial_balance(self, my_object, label):
"""Write a specific initial balance line on current line """Write a specific initial balance line on current line
using defined columns field_initial_balance name. using defined columns field_initial_balance name.
Columns are defined with `_get_report_columns` method. Columns are defined with `_get_report_columns` method.
""" """
col_pos_label = self._get_col_pos_initial_balance_label() col_pos_label = self._get_col_pos_initial_balance_label()
@ -257,10 +291,46 @@ class AbstractReportXslx(models.AbstractModel):
) )
self.row_pos += 1 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): def write_ending_balance(self, my_object, name, label):
"""Write a specific ending balance line on current line """Write a specific ending balance line on current line
using defined columns field_final_balance name. using defined columns field_final_balance name.
Columns are defined with `_get_report_columns` method. Columns are defined with `_get_report_columns` method.
""" """
for i in range(0, len(self.columns)): for i in range(0, len(self.columns)):
@ -305,6 +375,54 @@ class AbstractReportXslx(models.AbstractModel):
) )
self.row_pos += 1 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): def _get_currency_amt_format(self, line_object):
""" Return amount format specific for each currency. """ """ Return amount format specific for each currency. """
if hasattr(line_object, 'account_group_id') and \ if hasattr(line_object, 'account_group_id') and \
@ -327,6 +445,30 @@ class AbstractReportXslx(models.AbstractModel):
format_amt.set_num_format(format_amount) format_amt.set_num_format(format_amount)
return format_amt 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): def _get_currency_amt_header_format(self, line_object):
""" Return amount header format for each currency. """ """ Return amount header format for each currency. """
format_amt = getattr(self, 'format_header_amount') format_amt = getattr(self, 'format_header_amount')
@ -346,24 +488,42 @@ class AbstractReportXslx(models.AbstractModel):
format_amt.set_num_format(format_amount) format_amt.set_num_format(format_amount)
return format_amt 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. Allow to fetch report content to be displayed.
""" """
raise NotImplementedError() raise NotImplementedError()
def _get_report_complete_name(self, report, prefix):
def _get_report_complete_name(self, report, prefix, data=None):
if report.company_id: if report.company_id:
suffix = ' - %s - %s' % ( suffix = ' - %s - %s' % (
report.company_id.name, report.company_id.currency_id.name) report.company_id.name, report.company_id.currency_id.name)
return prefix + suffix return prefix + suffix
return prefix return prefix
def _get_report_name(self, report):
def _get_report_name(self, report, data=False):
""" """
Allow to define the report name. Allow to define the report name.
Report name will be used as sheet name and as report title. Report name will be used as sheet name and as report title.
:return: the report name :return: the report name
""" """
raise NotImplementedError() raise NotImplementedError()
@ -379,11 +539,8 @@ class AbstractReportXslx(models.AbstractModel):
""" """
Allow to define the report columns Allow to define the report columns
which will be used to generate report. which will be used to generate report.
:return: the report columns as dict :return: the report columns as dict
:Example: :Example:
{ {
0: {'header': 'Simple column', 0: {'header': 'Simple column',
'field': 'field_name_on_my_object', 'field': 'field_name_on_my_object',
@ -399,9 +556,7 @@ class AbstractReportXslx(models.AbstractModel):
def _get_report_filters(self, report): def _get_report_filters(self, report):
""" """
:return: the report filters as list :return: the report filters as list
:Example: :Example:
[ [
['first_filter_name', 'first_filter_value'], ['first_filter_name', 'first_filter_value'],
['second_filter_name', 'second_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) # © 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). # 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 @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: 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 @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' _name = 'report.a_f_r.report_aged_partner_balance_xlsx'
_inherit = 'report.account_financial_report.abstract_report_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') 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): def _get_report_columns(self, report):
if not report.show_move_line_details: if not report.show_move_line_details:
return { return {
0: {'header': _('Partner'), 'field': 'partner', 'width': 70},
0: {'header': _('Partner'), 'field': 'name', 'width': 70},
1: {'header': _('Residual'), 1: {'header': _('Residual'),
'field': 'amount_residual',
'field_footer_total': 'cumul_amount_residual',
'field': 'residual',
'field_footer_total': 'residual',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
2: {'header': _('Current'), 2: {'header': _('Current'),
'field': 'current', 'field': 'current',
'field_footer_total': 'cumul_current',
'field_footer_total': 'current',
'field_footer_percent': 'percent_current', 'field_footer_percent': 'percent_current',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
3: {'header': _(u'Age ≤ 30 d.'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
4: {'header': _(u'Age ≤ 60 d.'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
5: {'header': _(u'Age ≤ 90 d.'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
6: {'header': _(u'Age ≤ 120 d.'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
7: {'header': _('Older'), 7: {'header': _('Older'),
'field': 'older', 'field': 'older',
'field_footer_total': 'cumul_older',
'field_footer_total': 'older',
'field_footer_percent': 'percent_older', 'field_footer_percent': 'percent_older',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
@ -66,52 +72,52 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
2: {'header': _('Journal'), 'field': 'journal', 'width': 8}, 2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
3: {'header': _('Account'), 'field': 'account', 'width': 9}, 3: {'header': _('Account'), 'field': 'account', 'width': 9},
4: {'header': _('Partner'), 'field': 'partner', 'width': 25}, 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'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
8: {'header': _('Current'), 8: {'header': _('Current'),
'field': 'current', 'field': 'current',
'field_footer_total': 'cumul_current',
'field_footer_total': 'current',
'field_footer_percent': 'percent_current', 'field_footer_percent': 'percent_current',
'field_final_balance': 'current', 'field_final_balance': 'current',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
9: {'header': _(u'Age ≤ 30 d.'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
10: {'header': _(u'Age ≤ 60 d.'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
11: {'header': _(u'Age ≤ 90 d.'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
12: {'header': _(u'Age ≤ 120 d.'), 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', 'type': 'amount',
'width': 14}, 'width': 14},
13: {'header': _('Older'), 13: {'header': _('Older'),
'field': 'older', 'field': 'older',
'field_footer_total': 'cumul_older',
'field_footer_total': 'older',
'field_footer_percent': 'percent_older', 'field_footer_percent': 'percent_older',
'field_final_balance': 'older', 'field_final_balance': 'older',
'type': 'amount', 'type': 'amount',
@ -120,9 +126,9 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
def _get_report_filters(self, report): def _get_report_filters(self, report):
return [ return [
[_('Date at filter'), report.date_at],
[_('Date at filter'), report.date_at.strftime("%d/%m/%Y")],
[_('Target moves filter'), [_('Target moves filter'),
_('All posted entries') if report.only_posted_moves else _(
_('All posted entries') if report.target_move == 'posted' else _(
'All entries')], 'All entries')],
] ]
@ -141,94 +147,89 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
def _get_col_pos_final_balance_label(self): def _get_col_pos_final_balance_label(self):
return 5 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 each account
for account in report.account_ids:
for account in aged_partner_balance:
# Write account title # 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 # Display array header for partners lines
self.write_array_header() self.write_array_header()
# Display partner lines # 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 # 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 # 2 lines break
self.row_pos += 2 self.row_pos += 2
else: else:
# For each account # For each account
for account in report.account_ids:
for account in aged_partner_balance:
# Write account title # Write account title
self.write_array_title(account.code + ' - ' + account.name)
self.write_array_title(account['code'] + ' - ' + account[
'name'])
# For each partner # For each partner
for partner in account.partner_ids:
for partner in account['partners']:
# Write partner title # Write partner title
self.write_array_title(partner.name)
self.write_array_title(partner['name'])
# Display array header for move lines # Display array header for move lines
self.write_array_header() self.write_array_header()
# Display account move lines # 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 # Display ending balance line for partner
self.write_ending_balance(partner.line_ids)
self.write_ending_balance_from_dict(partner)
# Line break # Line break
self.row_pos += 1 self.row_pos += 1
# Display account lines # 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 # 2 lines break
self.row_pos += 2 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 Specific function to write ending partner balance
for Aged Partner Balance for Aged Partner Balance
""" """
name = None name = None
label = _('Partner cumul aged balance') label = _('Partner cumul aged balance')
super(AgedPartnerBalanceXslx, self).write_ending_balance(
super(AgedPartnerBalanceXslx, self).write_ending_balance_from_dict(
my_object, name, label 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 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: if col_pos == col_pos_footer_label:
value = label value = label
else: else:
value = getattr(account, column[field_name])
value = account.get(column[field_name], False)
cell_type = column.get('type', 'string') cell_type = column.get('type', 'string')
if cell_type == 'string' or col_pos == col_pos_footer_label: if cell_type == 'string' or col_pos == col_pos_footer_label:
self.sheet.write_string(self.row_pos, col_pos, value or '', 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' _name = 'report.a_f_r.report_general_ledger_xlsx'
_inherit = 'report.account_financial_report.abstract_report_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') 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): def _get_report_columns(self, report):
res = { res = {
@ -24,15 +30,15 @@ class GeneralLedgerXslx(models.AbstractModel):
4: {'header': _('Taxes'), 4: {'header': _('Taxes'),
'field': 'taxes_description', 'field': 'taxes_description',
'width': 15}, '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'), 7: {'header': _('Cost center'),
'field': 'cost_center', 'field': 'cost_center',
'width': 15}, 'width': 15},
8: {'header': _('Tags'), 8: {'header': _('Tags'),
'field': 'tags', 'field': 'tags',
'width': 10}, 'width': 10},
9: {'header': _('Rec.'), 'field': 'matching_number', 'width': 5},
9: {'header': _('Rec.'), 'field': 'rec_name', 'width': 5},
10: {'header': _('Debit'), 10: {'header': _('Debit'),
'field': 'debit', 'field': 'debit',
'field_initial_balance': 'initial_debit', 'field_initial_balance': 'initial_debit',
@ -46,7 +52,7 @@ class GeneralLedgerXslx(models.AbstractModel):
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
12: {'header': _('Cumul. Bal.'), 12: {'header': _('Cumul. Bal.'),
'field': 'cumul_balance',
'field': 'balance',
'field_initial_balance': 'initial_balance', 'field_initial_balance': 'initial_balance',
'field_final_balance': 'final_balance', 'field_final_balance': 'final_balance',
'type': 'amount', 'type': 'amount',
@ -55,15 +61,15 @@ class GeneralLedgerXslx(models.AbstractModel):
if report.foreign_currency: if report.foreign_currency:
foreign_currency = { foreign_currency = {
13: {'header': _('Cur.'), 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.'), 14: {'header': _('Amount cur.'),
'field': 'amount_currency',
'field': 'bal_curr',
'field_initial_balance': 'field_initial_balance':
'initial_balance_foreign_currency',
'initial_bal_curr',
'field_final_balance': 'field_final_balance':
'final_balance_foreign_currency',
'final_bal_curr',
'type': 'amount_currency', 'type': 'amount_currency',
'width': 14}, 'width': 14},
} }
@ -78,8 +84,8 @@ class GeneralLedgerXslx(models.AbstractModel):
], ],
[ [
_('Target moves filter'), _('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'), _('Account balance at 0 filter'),
@ -114,71 +120,161 @@ class GeneralLedgerXslx(models.AbstractModel):
def _get_col_pos_final_balance_label(self): def _get_col_pos_final_balance_label(self):
return 5 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 each account
for account in report.account_ids:
for account in general_ledger:
# Write account title # 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 # Display array header for move lines
self.write_array_header() self.write_array_header()
# Display initial balance line for account # 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 # 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: else:
# For each partner # For each partner
for partner in account.partner_ids:
for partner in account['list_partner']:
# Write partner title # Write partner title
self.write_array_title(partner.name)
self.write_array_title(partners_data[partner['id']]['name'])
# Display array header for move lines # Display array header for move lines
self.write_array_header() self.write_array_header()
# Display initial balance line for partner # 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 # 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 # 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 # Line break
self.row_pos += 1 self.row_pos += 1
# Display ending balance line for account # 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 # 2 lines break
self.row_pos += 2 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""" """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') 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') label = _('Initial balance')
super(GeneralLedgerXslx, self).write_initial_balance(
super(GeneralLedgerXslx, self).write_initial_balance_from_dict(
my_object, label 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""" """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') 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') label = _('Ending balance')
super(GeneralLedgerXslx, self).write_ending_balance(
super(GeneralLedgerXslx, self).write_ending_balance_from_dict(
my_object, name, label 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' _name = 'report.a_f_r.report_journal_ledger_xlsx'
_inherit = 'report.account_financial_report.abstract_report_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') 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): def _get_report_columns(self, report):
columns = [ columns = [
@ -36,7 +42,7 @@ class JournalLedgerXslx(models.AbstractModel):
if report.with_account_name: if report.with_account_name:
columns.append({ columns.append({
'header': _('Account Name'), 'header': _('Account Name'),
'field': 'account',
'field': 'account_name',
'width': 15 'width': 15
}) })
@ -74,9 +80,9 @@ class JournalLedgerXslx(models.AbstractModel):
columns += [ columns += [
{ {
'header': _('Currency'), 'header': _('Currency'),
'field': 'currency_id',
'type': 'many2one',
'width': 14
'field': 'currency_name',
'width': 14,
'type': 'currency_name',
}, },
{ {
'header': _('Amount Currency'), 'header': _('Amount Currency'),
@ -181,51 +187,61 @@ class JournalLedgerXslx(models.AbstractModel):
_('Journals'), _('Journals'),
', '.join([ ', '.join([
"%s - %s" % (report_journal.code, report_journal.name) "%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 group_option = report.group_option
if group_option == 'journal': 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': 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( 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" % ( 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( 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( 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" % ( 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( 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.workbook = workbook
self.sheet = workbook.add_worksheet(sheet_name) self.sheet = workbook.add_worksheet(sheet_name)
self._set_column_width() self._set_column_width()
@ -236,15 +252,45 @@ class JournalLedgerXslx(models.AbstractModel):
self.row_pos += 2 self.row_pos += 2
self.write_array_header() 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 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 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.workbook = workbook
self.sheet = workbook.add_worksheet(sheet_name) self.sheet = workbook.add_worksheet(sheet_name)
self.row_pos = 1 self.row_pos = 1
self.write_array_title(sheet_name) self.write_array_title(sheet_name)
self.row_pos += 2 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' _name = 'report.a_f_r.report_open_items_xlsx'
_inherit = 'report.account_financial_report.abstract_report_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') 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): def _get_report_columns(self, report):
res = { res = {
0: {'header': _('Date'), 'field': 'date', 'width': 11}, 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}, 2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
3: {'header': _('Account'), 'field': 'account', 'width': 9}, 3: {'header': _('Account'), 'field': 'account', 'width': 9},
4: {'header': _('Partner'), 'field': 'partner', 'width': 25}, 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'), 7: {'header': _('Original'),
'field': 'amount_total_due',
'field': 'original',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
8: {'header': _('Residual'), 8: {'header': _('Residual'),
'field': 'amount_residual', 'field': 'amount_residual',
'field_final_balance': 'final_amount_residual',
'field_final_balance': 'residual',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
} }
if report.foreign_currency: if report.foreign_currency:
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'), 10: {'header': _('Cur. Original'),
'field': 'amount_total_due_currency',
'field': 'amount_currency',
'field_final_balance': 'field_final_balance':
'final_amount_total_due_currency',
'amount_currency',
'type': 'amount_currency', 'type': 'amount_currency',
'width': 14}, 'width': 14},
11: {'header': _('Cur. Residual'), 11: {'header': _('Cur. Residual'),
'field': 'amount_residual_currency', 'field': 'amount_residual_currency',
'field_final_balance': 'field_final_balance':
'final_amount_residual_currency',
'amount_currency',
'type': 'amount_currency', 'type': 'amount_currency',
'width': 14}, 'width': 14},
} }
@ -55,9 +62,9 @@ class OpenItemsXslx(models.AbstractModel):
def _get_report_filters(self, report): def _get_report_filters(self, report):
return [ return [
[_('Date at filter'), report.date_at],
[_('Date at filter'), report.date_at.strftime("%d/%m/%Y")],
[_('Target moves filter'), [_('Target moves filter'),
_('All posted entries') if report.only_posted_moves else _(
_('All posted entries') if report.target_move == 'posted' else _(
'All entries')], 'All entries')],
[_('Account balance at 0 filter'), [_('Account balance at 0 filter'),
_('Hide') if report.hide_account_at_0 else _('Show')], _('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): def _get_col_pos_final_balance_label(self):
return 5 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 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 # 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 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""" """Specific function to write ending balance for Open Items"""
if type_object == 'partner': 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') label = _('Partner ending balance')
my_object.currency_id = my_object.report_account_id.currency_id
elif type_object == 'account': 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') 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"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<template id="report_aged_partner_balance_qweb">
<template id="aged_partner_balance">
<t t-call="web.html_container"> <t t-call="web.html_container">
<t t-foreach="docs" t-as="o"> <t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout"> <t t-call="account_financial_report.internal_layout">
@ -13,10 +13,9 @@
<template id="report_aged_partner_balance_base"> <template id="report_aged_partner_balance_base">
<!-- Saved flag fields into variables, used to define columns display --> <!-- 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 --> <!-- 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="page">
<div class="row"> <div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/> <h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
@ -24,15 +23,15 @@
<!-- Display filters --> <!-- Display filters -->
<t t-call="account_financial_report.report_aged_partner_balance_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"> <div class="page_break">
<!-- Display account header --> <!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;"/> <div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title" <div class="act_as_caption account_title"
style="width: 100%;"> style="width: 100%;">
<span t-field="account.code"/>
<span t-esc="account['code']"/>
- -
<span t-field="account.name"/>
<span t-esc="account['name']"/>
</div> </div>
<!-- Display account lines --> <!-- Display account lines -->
@ -42,8 +41,7 @@
<!-- Display account header --> <!-- Display account header -->
<t t-call="account_financial_report.report_aged_partner_balance_lines_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 --> <!-- Display one line per partner -->
<t t-call="account_financial_report.report_aged_partner_balance_lines"/> <t t-call="account_financial_report.report_aged_partner_balance_lines"/>
</t> </t>
@ -57,11 +55,11 @@
<t t-if="show_move_line_details"> <t t-if="show_move_line_details">
<!-- Display account partners --> <!-- Display account partners -->
<t t-foreach="account.partner_ids" t-as="partner">
<t t-foreach="account['partners']" t-as="partner">
<div class="page_break"> <div class="page_break">
<!-- Display partner header --> <!-- Display partner header -->
<div class="act_as_caption account_title"> <div class="act_as_caption account_title">
<span t-field="partner.name"/>
<span t-esc="partner['name']"/>
</div> </div>
<!-- Display partner move lines --> <!-- Display partner move lines -->
@ -69,7 +67,7 @@
<!-- Display partner footer --> <!-- Display partner footer -->
<t t-call="account_financial_report.report_aged_partner_balance_partner_ending_cumul"> <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> </t>
</div> </div>
</t> </t>
@ -90,11 +88,11 @@
</div> </div>
<div class="act_as_row"> <div class="act_as_row">
<div class="act_as_cell"> <div class="act_as_cell">
<span t-field="o.date_at"/>
<span t-esc="date_at"/>
</div> </div>
<div class="act_as_cell"> <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> </div>
</div> </div>
@ -125,44 +123,41 @@
</template> </template>
<template id="report_aged_partner_balance_lines"> <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> </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>
<template id="report_aged_partner_balance_move_lines"> <template id="report_aged_partner_balance_move_lines">
@ -210,180 +205,194 @@
</div> </div>
</div> </div>
<!-- Display each move lines --> <!-- 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 --> <!-- # lines or centralized lines -->
<div class="act_as_row lines"> <div class="act_as_row lines">
<!--## date--> <!--## date-->
<div class="act_as_cell left"> <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 --> <!--## 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> </div>
<!--## move--> <!--## move-->
<div class="act_as_cell left"> <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> </div>
<!--## journal--> <!--## journal-->
<div class="act_as_cell left"> <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> </div>
<!--## account code--> <!--## account code-->
<div class="act_as_cell left"> <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> </div>
<!--## partner--> <!--## partner-->
<div class="act_as_cell left"> <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> </div>
<!--## ref - label--> <!--## ref - label-->
<div class="act_as_cell left"> <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> </div>
<!--## date_due--> <!--## date_due-->
<div class="act_as_cell left"> <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 --> <!--## 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> </div>
<!--## amount_residual--> <!--## amount_residual-->
<div class="act_as_cell amount"> <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> </div>
<!--## current--> <!--## current-->
<div class="act_as_cell amount"> <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> </div>
<!--## age_30_days--> <!--## age_30_days-->
<div class="act_as_cell amount"> <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> </div>
<!--## age_60_days--> <!--## age_60_days-->
<div class="act_as_cell amount"> <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> </div>
<!--## age_90_days--> <!--## age_90_days-->
<div class="act_as_cell amount"> <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> </div>
<!--## age_120_days--> <!--## age_120_days-->
<div class="act_as_cell amount"> <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> </div>
<!--## older--> <!--## older-->
<div class="act_as_cell amount"> <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>
</div> </div>
</t> </t>
@ -401,31 +410,31 @@
<div class="act_as_cell" style="width: 6.00%;"/> <div class="act_as_cell" style="width: 6.00%;"/>
<!--## amount_residual--> <!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%;"> <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> </div>
<!--## current--> <!--## current-->
<div class="act_as_cell amount" style="width: 6.00%;"> <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> </div>
<!--## age_30_days--> <!--## age_30_days-->
<div class="act_as_cell amount" style="width: 6.00%;"> <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> </div>
<!--## age_60_days--> <!--## age_60_days-->
<div class="act_as_cell amount" style="width: 6.00%;"> <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> </div>
<!--## age_90_days--> <!--## age_90_days-->
<div class="act_as_cell amount" style="width: 6.00%;"> <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> </div>
<!--## age_120_days--> <!--## age_120_days-->
<div class="act_as_cell amount" style="width: 6.00%;"> <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> </div>
<!--## older--> <!--## older-->
<div class="act_as_cell amount" style="width: 6.00%;"> <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> </div>
</div> </div>
@ -440,31 +449,31 @@
<div class="act_as_cell right" style="width: 32.52%;">Total</div> <div class="act_as_cell right" style="width: 32.52%;">Total</div>
<!--## amount_residual--> <!--## amount_residual-->
<div class="act_as_cell amount" style="width: 9.64%;"> <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> </div>
<!--## current--> <!--## current-->
<div class="act_as_cell amount" style="width: 9.64%;"> <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> </div>
<!--## age_30_days--> <!--## age_30_days-->
<div class="act_as_cell amount" style="width: 9.64%;"> <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> </div>
<!--## age_60_days--> <!--## age_60_days-->
<div class="act_as_cell amount" style="width: 9.64%;"> <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> </div>
<!--## age_90_days--> <!--## age_90_days-->
<div class="act_as_cell amount" style="width: 9.64%;"> <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> </div>
<!--## age_120_days--> <!--## age_120_days-->
<div class="act_as_cell amount" style="width: 9.64%;"> <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> </div>
<!--## older--> <!--## older-->
<div class="act_as_cell amount" style="width: 9.64%;"> <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> </div>
</t> </t>
<t t-if="show_move_line_details"> <t t-if="show_move_line_details">
@ -474,31 +483,31 @@
<div class="act_as_cell" style="width: 6.00%;"/> <div class="act_as_cell" style="width: 6.00%;"/>
<!--## amount_residual--> <!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%"> <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> </div>
<!--## current--> <!--## current-->
<div class="act_as_cell amount" style="width: 6.00%"> <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> </div>
<!--## age_30_days--> <!--## age_30_days-->
<div class="act_as_cell amount" style="width: 6.00%"> <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> </div>
<!--## age_60_days--> <!--## age_60_days-->
<div class="act_as_cell amount" style="width: 6.00%"> <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> </div>
<!--## age_90_days--> <!--## age_90_days-->
<div class="act_as_cell amount" style="width: 6.00%"> <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> </div>
<!--## age_120_days--> <!--## age_120_days-->
<div class="act_as_cell amount" style="width: 6.00%"> <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> </div>
<!--## older--> <!--## older-->
<div class="act_as_cell amount" style="width: 6.00%"> <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> </div>
</t> </t>
</div> </div>
@ -510,23 +519,22 @@
<!--## amount_residual--> <!--## amount_residual-->
<div class="act_as_cell amount" style="width: 9.64%;"/> <div class="act_as_cell amount" style="width: 9.64%;"/>
<!--## current--> <!--## 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> </div>
<!--## age_30_days--> <!--## 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> </div>
<!--## age_60_days--> <!--## 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> </div>
<!--## age_90_days--> <!--## 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> </div>
<!--## age_120_days--> <!--## 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> </div>
<!--## older--> <!--## 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> </div>
</t> </t>
<t t-if="show_move_line_details"> <t t-if="show_move_line_details">
@ -538,22 +546,22 @@
<!--## amount_residual--> <!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%"/> <div class="act_as_cell amount" style="width: 6.00%"/>
<!--## current--> <!--## 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> </div>
<!--## age_30_days--> <!--## 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> </div>
<!--## age_60_days--> <!--## 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> </div>
<!--## age_90_days--> <!--## 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> </div>
<!--## age_120_days--> <!--## 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> </div>
<!--## older--> <!--## 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> </div>
</t> </t>
</div> </div>

347
account_financial_report/report/templates/general_ledger.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<template id="report_general_ledger_qweb">
<template id="general_ledger">
<t t-call="web.html_container"> <t t-call="web.html_container">
<t t-foreach="docs" t-as="o"> <t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout"> <t t-call="account_financial_report.internal_layout">
@ -13,28 +13,26 @@
<template id="report_general_ledger_base"> <template id="report_general_ledger_base">
<!-- Saved flag fields into variables, used to define columns display --> <!-- 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 --> <!-- 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="page">
<div class="row"> <div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/> <h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
</div> </div>
<!-- Display filters --> <!-- Display filters -->
<t t-call="account_financial_report.report_general_ledger_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"> <div class="page_break">
<!-- Display account header --> <!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;"/> <div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title" <div class="act_as_caption account_title"
style="width: 100%"> 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> </div>
<t t-if="not account.partner_ids">
<t t-if="not account['partners']">
<!-- Display account move lines without partner regroup --> <!-- Display account move lines without partner regroup -->
<t t-set="type" t-value='"account_type"'/> <t t-set="type" t-value='"account_type"'/>
<t t-call="account_financial_report.report_general_ledger_lines"> <t t-call="account_financial_report.report_general_ledger_lines">
@ -42,32 +40,35 @@
</t> </t>
</t> </t>
<t t-if="account.partner_ids">
<t t-if="account['partners']">
<!-- Display 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>
</t> </t>
<!-- Display account footer --> <!-- 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="account_or_partner_object" t-value="account"/>
<t t-set="type" t-value='"account_type"'/> <t t-set="type" t-value='"account_type"'/>
</t> </t>
@ -87,23 +88,23 @@
</div> </div>
<div class="act_as_row"> <div class="act_as_row">
<div class="act_as_cell"> <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>
<div class="act_as_cell"> <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 class="act_as_cell"> <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 class="act_as_cell"> <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>
<div class="act_as_cell"> <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> </div>
</div> </div>
@ -188,29 +189,29 @@
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<t t-if="type == 'account_type'"> <t t-if="type == 'account_type'">
<t t-set="domain" <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)]"/> ('debit', '&lt;&gt;', 0)]"/>
<span> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <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)]"/> ('debit', '&lt;&gt;', 0)]"/>
<span> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
</div> </div>
@ -218,29 +219,31 @@
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<t t-if="type == 'account_type'"> <t t-if="type == 'account_type'">
<t t-set="domain" <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)]"/> ('credit', '&lt;&gt;', 0)]"/>
<span> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <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)]"/> ('credit', '&lt;&gt;', 0)]"/>
<span> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
</div> </div>
@ -248,64 +251,66 @@
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<t t-if="type == 'account_type'"> <t t-if="type == 'account_type'">
<t t-set="domain" <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> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <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> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
</div> </div>
<t t-if="foreign_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%;"> <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>
<div class="act_as_cell amount" style="width: 5.19%;"> <div class="act_as_cell amount" style="width: 5.19%;">
<t t-if="type == 'account_type'"> <t t-if="type == 'account_type'">
<t t-set="domain" <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)]"/> ('date', '&lt;', o.date_from)]"/>
<span> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
<t t-if="type == 'partner_type'"> <t t-if="type == 'partner_type'">
<t t-set="domain" <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)]"/> ('date', '&lt;', o.date_from)]"/>
<span> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
</div> </div>
</t> </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: 2.08%;"/>
<div class="act_as_cell" style="width: 5.19%;"/> <div class="act_as_cell" style="width: 5.19%;"/>
</t> </t>
@ -313,76 +318,102 @@
</div> </div>
<!-- Display each lines --> <!-- 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 --> <!-- # lines or centralized lines -->
<div class="act_as_row lines"> <div class="act_as_row lines">
<!--## date--> <!--## date-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move.line'"/> <t t-set="res_model" t-value="'account.move.line'"/>
<span> <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> </span>
</div> </div>
<!--## move--> <!--## move-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move'"/> <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> </div>
<!--## journal--> <!--## journal-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<t t-set="res_model" t-value="'account.journal'"/> <t t-set="res_model" t-value="'account.journal'"/>
<span> <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" t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action" class="o_account_financial_reports_web_action"
style="color: black;"> 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> </span>
</div> </div>
<!--## account code--> <!--## account code-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<t t-set="res_model" t-value="'account.account'"/> <t t-set="res_model" t-value="'account.account'"/>
<span> <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" t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action" class="o_account_financial_reports_web_action"
style="color: black;"> style="color: black;">
<t t-raw="line.account"/></a>
<t t-raw="o._get_atr_from_dict(account['id'], accounts_data, 'code')"/></a>
</span> </span>
</div> </div>
<!--## taxes--> <!--## 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--> <!--## partner-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<t t-set="res_model" t-value="'res.partner'"/> <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" t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action" 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> </span>
</div> </div>
<!--## ref - label--> <!--## ref - label-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move.line'"/> <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> </div>
<!--## cost_center--> <!--## cost_center-->
<t t-if="show_cost_center"> <t t-if="show_cost_center">
@ -398,71 +429,105 @@
</t> </t>
<t t-if="show_analytic_tags"> <t t-if="show_analytic_tags">
<!--## 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> </t>
<!--## matching_number--> <!--## matching_number-->
<div class="act_as_cell"> <div class="act_as_cell">
<t t-set="res_model" t-value="'account.full.reconcile'"/> <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" t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action" 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> </span>
</div> </div>
<!--## debit--> <!--## debit-->
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<t t-set="res_model" t-value="'account.move.line'"/> <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> </div>
<!--## credit--> <!--## credit-->
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<t t-set="res_model" t-value="'account.move.line'"/> <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> </div>
<!--## balance cumulated--> <!--## balance cumulated-->
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<t t-set="res_model" t-value="'account.move.line'"/> <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> </div>
<t t-if="foreign_currency"> <t t-if="foreign_currency">
<t t-if="line.currency_id.id">
<t t-if="line['currency_id']">
<!--## currency_name--> <!--## currency_name-->
<div class="act_as_cell amount" style="width: 2.08%;"> <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> </div>
<!--## amount_currency--> <!--## amount_currency-->
<div class="act_as_cell amount" style="width: 5.19%;"> <div class="act_as_cell amount" style="width: 5.19%;">
<t t-set="res_model" t-value="'account.move.line'"/> <t t-set="res_model" t-value="'account.move.line'"/>
<span> <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" t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action" class="o_account_financial_reports_web_action"
style="color: black;"> 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> </span>
</div> </div>
</t> </t>
<t t-if="not line.currency_id.id">
<t t-if="not line['currency_id']">
<!--## currency_name--> <!--## currency_name-->
<div class="act_as_cell amount" style="width: 2.08%;"/> <div class="act_as_cell amount" style="width: 2.08%;"/>
<!--## amount_currency--> <!--## amount_currency-->
@ -482,7 +547,7 @@
<t t-if='type == "account_type"'> <t t-if='type == "account_type"'>
<div class="act_as_cell first_column" <div class="act_as_cell first_column"
style="width: 41.32%;"><span 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" <div class="act_as_cell right"
style="width: 22.9%;">Ending balance</div> style="width: 22.9%;">Ending balance</div>
</t> </t>
@ -502,51 +567,53 @@
<div class="act_as_cell" style="width: 2.41%;"/> <div class="act_as_cell" style="width: 2.41%;"/>
<!--## debit--> <!--## debit-->
<div class="act_as_cell amount" style="width: 6.02%;"> <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> </div>
<!--## credit--> <!--## credit-->
<div class="act_as_cell amount" style="width: 6.02%;"> <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> </div>
<!--## balance cumulated--> <!--## balance cumulated-->
<div class="act_as_cell amount" style="width: 6.02%;"> <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> </div>
<!--## currency_name + amount_currency--> <!--## currency_name + amount_currency-->
<t t-if="foreign_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%;"> <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>
<div class="act_as_cell amount" style="width: 5.19%;"> <div class="act_as_cell amount" style="width: 5.19%;">
<t t-if="type == 'account_type'"> <t t-if="type == 'account_type'">
<t t-set="domain" <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> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
<t t-if="type == 'partner_type'"> <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> <span>
<a t-att-data-domain="domain" <a t-att-data-domain="domain"
t-att-data-res-model="'account.move.line'" t-att-data-res-model="'account.move.line'"
class="o_account_financial_reports_web_action_monetary_multi" class="o_account_financial_reports_web_action_monetary_multi"
style="color: black;"> 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> </span>
</t> </t>
</div> </div>
</t> </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: 2.08%;"/>
<div class="act_as_cell amount" style="width: 5.19%;"/> <div class="act_as_cell amount" style="width: 5.19%;"/>
</t> </t>

110
account_financial_report/report/templates/journal_ledger.xml

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="utf-8"?> <?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> <odoo>
<template id="report_journal_ledger_qweb">
<template id="journal_ledger">
<t t-call="web.html_container"> <t t-call="web.html_container">
<t t-foreach="docs" t-as="o"> <t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout"> <t t-call="account_financial_report.internal_layout">
@ -12,23 +15,23 @@
</template> </template>
<template id="report_journal_ledger_base"> <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="page">
<div class="row"> <div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/> <h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
</div> </div>
<t t-if="o.group_option == 'none'">
<t t-if="group_option == 'none'">
<div class="page_break"> <div class="page_break">
<t t-call="account_financial_report.report_journal_all"/> <t t-call="account_financial_report.report_journal_all"/>
<br/> <br/>
<t t-call="account_financial_report.report_journal_all_taxes"/> <t t-call="account_financial_report.report_journal_all_taxes"/>
</div> </div>
</t> </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"> <div class="page_break">
<t t-call="account_financial_report.report_journal_ledger_journal"/> <t t-call="account_financial_report.report_journal_ledger_journal"/>
<br/> <br/>
@ -44,7 +47,7 @@
<div class="act_as_table list_table" style="margin-top: 10px;"/> <div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_table data_table" style="width: 100%;"> <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_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 t-call="account_financial_report.report_journal_move"/>
</t> </t>
</div> </div>
@ -53,13 +56,13 @@
<template id="account_financial_report.report_journal_ledger_journal"> <template id="account_financial_report.report_journal_ledger_journal">
<div class="act_as_table list_table" style="margin-top: 10px;"/> <div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title" style="width: 100%;"> <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>
<div class="act_as_table data_table" style="width: 100%;"> <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_table_header"/>
<t t-call="account_financial_report.report_journal_ledger_journal_first_line"/> <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 t-call="account_financial_report.report_journal_move"/>
</t> </t>
</div> </div>
@ -155,11 +158,11 @@
name="taxes"/> name="taxes"/>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="debit"> name="debit">
<b><span t-field="journal.debit"/></b>
<b><span t-esc="journal['debit']" t-options="{'widget': 'float', 'precision': 2}"/></b>
</div> </div>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="credit"> name="credit">
<b><span t-field="journal.credit"/></b>
<b><span t-esc="journal['credit']" t-options="{'widget': 'float', 'precision': 2}"/></b>
</div> </div>
<t t-if="display_currency"> <t t-if="display_currency">
<div class="act_as_cell" <div class="act_as_cell"
@ -177,9 +180,9 @@
<t t-set="display_move_info" t-value="True"/> <t t-set="display_move_info" t-value="True"/>
<t t-set="last_partner" t-eval="None"/> <t t-set="last_partner" t-eval="None"/>
<t t-set="display_partner" t-eval="True"/> <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"> <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-set="display_partner" t-value="current_partner != last_partner"/>
<t t-call="account_financial_report.report_journal_move_line"/> <t t-call="account_financial_report.report_journal_move_line"/>
<t t-set="last_partner" t-value="current_partner"/> <t t-set="last_partner" t-value="current_partner"/>
@ -191,54 +194,65 @@
<template id="account_financial_report.report_journal_move_line"> <template id="account_financial_report.report_journal_move_line">
<div class="act_as_cell left" <div class="act_as_cell left"
name="entry"> 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>
<div class="act_as_cell left" <div class="act_as_cell left"
name="date"> 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>
<div class="act_as_cell left" <div class="act_as_cell left"
name="account"> 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-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> </span>
</div> </div>
<div class="act_as_cell left" <div class="act_as_cell left"
name="partner"> 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>
<div class="act_as_cell left" <div class="act_as_cell left"
name="label"> 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>
<div class="act_as_cell left" <div class="act_as_cell left"
name="taxes"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="debit"> 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> </t>
</div> </div>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="credit"> 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> </t>
</div> </div>
<t t-if="display_currency"> <t t-if="display_currency">
<div class="act_as_cell" <div class="act_as_cell"
name="currency_name"> 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> </t>
</div> </div>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="amount_currency"> 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> </t>
</div> </div>
</t> </t>
@ -314,39 +328,39 @@
</div> </div>
</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_row lines">
<div class="act_as_cell left" <div class="act_as_cell left"
name="tax_name"> name="tax_name">
<span t-field="tax_line.tax_name"/>
<span t-esc="tax_line['tax_name']"/>
</div> </div>
<div class="act_as_cell left" <div class="act_as_cell left"
name="tax_code"> name="tax_code">
<span t-field="tax_line.tax_code"/>
<span t-esc="tax_line['tax_code']"/>
</div> </div>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="base_debit"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="base_credit"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="base_balance"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="tax_debit"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="tax_credit"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="tax_balance"> 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>
</div> </div>
</t> </t>
@ -423,39 +437,39 @@
</div> </div>
</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_row lines">
<div class="act_as_cell left" <div class="act_as_cell left"
name="tax_name"> name="tax_name">
<span t-field="tax_line.tax_name"/>
<span t-esc="tax_line['tax_name']"/>
</div> </div>
<div class="act_as_cell left" <div class="act_as_cell left"
name="tax_code"> name="tax_code">
<span t-field="tax_line.tax_code"/>
<span t-esc="tax_line['tax_code']"/>
</div> </div>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="base_debit"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="base_credit"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="base_balance"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="tax_debit"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="tax_credit"> 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>
<div class="act_as_cell amount" <div class="act_as_cell amount"
name="tax_balance"> 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>
</div> </div>
</t> </t>

106
account_financial_report/report/templates/open_items.xml

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<template id="account_financial_report.report_open_items_qweb">
<template id="open_items">
<t t-call="web.html_container"> <t t-call="web.html_container">
<t t-foreach="docs" t-as="o"> <t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout"> <t t-call="account_financial_report.internal_layout">
@ -13,10 +13,10 @@
<template id="account_financial_report.report_open_items_base"> <template id="account_financial_report.report_open_items_base">
<!-- Saved flag fields into variables, used to define columns display --> <!-- 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 --> <!-- 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="page">
<div class="row"> <div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/> <h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
@ -24,23 +24,23 @@
<!-- Display filters --> <!-- Display filters -->
<t t-call="account_financial_report.report_open_items_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"> <div class="page_break">
<!-- Display account header --> <!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;" /> <div class="act_as_table list_table" style="margin-top: 10px;" />
<div class="account_title" <div class="account_title"
style="width: 100%;"> 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> </div>
<!-- Display account partners --> <!-- 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"> <div class="page_break">
<!-- Display partner header --> <!-- 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> </div>
<!-- Display partner move lines --> <!-- Display partner move lines -->
@ -48,7 +48,8 @@
<!-- Display partner footer --> <!-- Display partner footer -->
<t t-call="account_financial_report.report_open_items_ending_cumul"> <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 t-set="type" t-value='"partner_type"'/>
</t> </t>
</div> </div>
@ -56,7 +57,8 @@
<!-- Display account footer --> <!-- Display account footer -->
<t t-call="account_financial_report.report_open_items_ending_cumul"> <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 t-set="type" t-value='"account_type"'/>
</t> </t>
</div> </div>
@ -73,15 +75,15 @@
</div> </div>
<div class="act_as_row"> <div class="act_as_row">
<div class="act_as_cell"> <div class="act_as_cell">
<span t-field="o.date_at"/>
<span t-esc="date_at"/>
</div> </div>
<div class="act_as_cell"> <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>
<div class="act_as_cell"> <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> </div>
</div> </div>
@ -127,78 +129,71 @@
</div> </div>
<!-- Display each lines --> <!-- 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 --> <!-- # lines or centralized lines -->
<div class="act_as_row lines"> <div class="act_as_row lines">
<!--## date--> <!--## date-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<span t-field="line.date"/>
<span t-raw="line['date']"/>
</div> </div>
<!--## move--> <!--## move-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<t t-set="res_model" t-value="'account.move'"/> <t t-set="res_model" t-value="'account.move'"/>
<span> <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" t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action" class="o_account_financial_reports_web_action"
style="color: black;"> style="color: black;">
<t t-raw="line.entry"/>
<t t-esc="line['move_name']"/>
</a> </a>
</span> </span>
</div> </div>
<!--## journal--> <!--## journal-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<span t-field="line.journal"/>
<span t-esc="line['journal']"/>
</div> </div>
<!--## account code--> <!--## account code-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<span t-field="line.account"/>
<span t-esc="line['account']"/>
</div> </div>
<!--## partner--> <!--## partner-->
<div class="act_as_cell left"> <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> </div>
<!--## ref - label--> <!--## ref - label-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<span t-field="line.label"/>
<span t-esc="line['ref']"/>
</div> </div>
<!--## date_due--> <!--## date_due-->
<div class="act_as_cell left"> <div class="act_as_cell left">
<span t-field="line.date_due"/>
<span t-esc="line['date_maturity']"/>
</div> </div>
<!--## amount_total_due--> <!--## amount_total_due-->
<div class="act_as_cell amount"> <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> </div>
<!--## amount_residual--> <!--## amount_residual-->
<div class="act_as_cell amount"> <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> </div>
<t t-if="foreign_currency"> <t t-if="foreign_currency">
<t t-if="line.currency_id.id">
<t t-if="line['currency_id']">
<!--## currency_name--> <!--## currency_name-->
<div class="act_as_cell amount"> <div class="act_as_cell amount">
<span t-field="line.currency_id.display_name"/>
<span t-esc="line['currency_name']"/>
</div> </div>
<!--## amount_total_due_currency--> <!--## amount_total_due_currency-->
<div class="act_as_cell amount"> <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> </div>
<!--## amount_residual_currency--> <!--## amount_residual_currency-->
<div class="act_as_cell amount"> <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> </div>
</t> </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"/> <div class="act_as_cell"/>
<!--## amount_total_due_currency--> <!--## amount_total_due_currency-->
<div class="act_as_cell"/> <div class="act_as_cell"/>
@ -218,9 +213,9 @@
<!--## date--> <!--## date-->
<t t-if='type == "account_type"'> <t t-if='type == "account_type"'>
<div class="act_as_cell first_column" style="width: 36.34%;"> <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>
<div class="act_as_cell right" style="width: 28.66%;">Ending <div class="act_as_cell right" style="width: 28.66%;">Ending
balance</div> balance</div>
@ -237,32 +232,21 @@
<div class="act_as_cell amount" style="width: 6.57%;"/> <div class="act_as_cell amount" style="width: 6.57%;"/>
<!--## amount_currency--> <!--## amount_currency-->
<div class="act_as_cell amount" style="width: 6.57%;"> <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> </div>
<!--## amount_total_due_currency + amount_residual_currency --> <!--## amount_total_due_currency + amount_residual_currency -->
<t t-if="foreign_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--> <!--## currency_name-->
<div class="act_as_cell"/> <div class="act_as_cell"/>
<!--## amount_total_due_currency--> <!--## amount_total_due_currency-->
<div class="act_as_cell"/> <div class="act_as_cell"/>
<!--## amount_residual_currency--> <!--## amount_residual_currency-->
<div class="act_as_cell"/> <div class="act_as_cell"/>
</t>
</t> </t>
</div> </div>
</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"?> <?xml version="1.0" encoding="utf-8"?>
<odoo> <odoo>
<template id="account_financial_report.report_vat_report_qweb">
<template id="vat_report">
<t t-call="web.html_container"> <t t-call="web.html_container">
<t t-foreach="docs" t-as="o"> <t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout"> <t t-call="account_financial_report.internal_layout">
@ -12,8 +12,8 @@
</template> </template>
<template id="account_financial_report.report_vat_report_base"> <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="page">
<div class="row"> <div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/> <h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
@ -36,105 +36,101 @@
</div> </div>
</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;"> <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%;"> <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>
<div class="act_as_cell left oe_tooltip_string" style="width: 65%;"> <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>
<div class="act_as_cell amount" style="width: 15%;"> <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>
<div class="act_as_cell amount" style="width: 15%;"> <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>
</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_row lines">
<div class="act_as_cell" style="width: 5%;"/> <div class="act_as_cell" style="width: 5%;"/>
<div class="act_as_cell left oe_tooltip_string" style="padding-left: 20px; width: 65%;"> <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>
<div class="act_as_cell amount" style="width: 15%;"> <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>
<div class="act_as_cell amount" style="width: 15%;"> <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>
</div> </div>
</t> </t>
@ -153,13 +149,13 @@
</div> </div>
<div class="act_as_row"> <div class="act_as_row">
<div class="act_as_cell"> <div class="act_as_cell">
<span t-field="o.date_from"/>
<span t-esc="date_from"/>
</div> </div>
<div class="act_as_cell"> <div class="act_as_cell">
<span t-field="o.date_to"/>
<span t-esc="date_to"/>
</div> </div>
<div class="act_as_cell"> <div class="act_as_cell">
<span t-field="o.based_on"/>
<span t-esc="based_on"/>
</div> </div>
</div> </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' _name = 'report.a_f_r.report_trial_balance_xlsx'
_inherit = 'report.account_financial_report.abstract_report_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') 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): def _get_report_columns(self, report):
if not report.show_partner_details: if not report.show_partner_details:
@ -73,11 +79,11 @@ class TrialBalanceXslx(models.AbstractModel):
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
4: {'header': _('Period balance'), 4: {'header': _('Period balance'),
'field': 'period_balance',
'field': 'balance',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
5: {'header': _('Ending balance'), 5: {'header': _('Ending balance'),
'field': 'final_balance',
'field': 'ending_balance',
'type': 'amount', 'type': 'amount',
'width': 14}, 'width': 14},
} }
@ -88,11 +94,11 @@ class TrialBalanceXslx(models.AbstractModel):
'field_currency_balance': 'currency_id', 'field_currency_balance': 'currency_id',
'type': 'many2one', 'width': 7}, 'type': 'many2one', 'width': 7},
7: {'header': _('Initial balance'), 7: {'header': _('Initial balance'),
'field': 'initial_balance_foreign_currency',
'field': 'initial_currency_balance',
'type': 'amount_currency', 'type': 'amount_currency',
'width': 14}, 'width': 14},
8: {'header': _('Ending balance'), 8: {'header': _('Ending balance'),
'field': 'final_balance_foreign_currency',
'field': 'ending_currency_balance',
'type': 'amount_currency', 'type': 'amount_currency',
'width': 14}, 'width': 14},
} }
@ -104,7 +110,7 @@ class TrialBalanceXslx(models.AbstractModel):
[_('Date range filter'), [_('Date range filter'),
_('From: %s To: %s') % (report.date_from, report.date_to)], _('From: %s To: %s') % (report.date_from, report.date_to)],
[_('Target moves filter'), [_('Target moves filter'),
_('All posted entries') if report.only_posted_moves else _(
_('All posted entries') if report.target_move == 'all' else _(
'All entries')], 'All entries')],
[_('Account at 0 filter'), [_('Account at 0 filter'),
_('Hide') if report.hide_account_at_0 else _('Show')], _('Hide') if report.hide_account_at_0 else _('Show')],
@ -121,37 +127,87 @@ class TrialBalanceXslx(models.AbstractModel):
def _get_col_count_filter_value(self): def _get_col_count_filter_value(self):
return 3 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 # Display array header for account lines
self.write_array_header() self.write_array_header()
# For each account # 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 # 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 # Display array header for partner lines
self.write_array_header() self.write_array_header()
# For each partner # 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 # 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 # Line break
self.row_pos += 2 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): def write_line(self, line_object, type_object):
"""Write a line on current line using all defined columns field name. """Write a line on current line using all defined columns field name.
Columns are defined with `_get_report_columns` method. Columns are defined with `_get_report_columns` method.
@ -164,12 +220,12 @@ class TrialBalanceXslx(models.AbstractModel):
def write_account_footer(self, account, name_value): def write_account_footer(self, account, name_value):
"""Specific function to write account footer for Trial Balance""" """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(): for col_pos, column in self.columns.items():
if column['field'] == 'name': if column['field'] == 'name':
value = name_value value = name_value
else: else:
value = getattr(account, column['field'])
value = account[column['field']]
cell_type = column.get('type', 'string') cell_type = column.get('type', 'string')
if cell_type == 'string': if cell_type == 'string':
self.sheet.write_string(self.row_pos, col_pos, value or '', self.sheet.write_string(self.row_pos, col_pos, value or '',
@ -177,11 +233,11 @@ class TrialBalanceXslx(models.AbstractModel):
elif cell_type == 'amount': elif cell_type == 'amount':
self.sheet.write_number(self.row_pos, col_pos, float(value), self.sheet.write_number(self.row_pos, col_pos, float(value),
self.format_header_amount) self.format_header_amount)
elif cell_type == 'many2one':
elif cell_type == 'many2one' and account['currency_id']:
self.sheet.write_string( self.sheet.write_string(
self.row_pos, col_pos, value.name or '', self.row_pos, col_pos, value.name or '',
self.format_header_right) 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.sheet.write_number(
self.row_pos, col_pos, float(value), self.row_pos, col_pos, float(value),
format_amt) format_amt)

525
account_financial_report/report/vat_report.py

@ -1,356 +1,189 @@
# Copyright 2018 Forest and Biomass Romania # 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). # 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 @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' _name = 'report.a_f_r.report_vat_report_xlsx'
_inherit = 'report.account_financial_report.abstract_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): def _get_report_columns(self, report):
return { return {
@ -28,9 +34,10 @@ class VATReportXslx(models.AbstractModel):
def _get_report_filters(self, report): def _get_report_filters(self, report):
return [ 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): def _get_col_count_filter_name(self):
@ -39,14 +46,19 @@ class VATReportXslx(models.AbstractModel):
def _get_col_count_filter_value(self): def _get_col_count_filter_value(self):
return 2 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() self.write_array_header()
for taxtag in report.taxtags_ids:
for tag_or_group in vat_report:
# Write taxtag line # Write taxtag line
self.write_line(taxtag)
self.write_line_from_dict(tag_or_group)
# For each tax if detail taxes # 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 --> <!-- General Ledger -->
<report <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" string="General Ledger"
report_type="qweb-pdf" 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 <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" string="General Ledger"
report_type="qweb-html" 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 --> <!-- 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 --> <!-- Trial Balance -->
<report <report
id="action_report_trial_balance_qweb" id="action_report_trial_balance_qweb"
model="report_trial_balance"
model="trial.balance.report.wizard"
string="Trial Balance" string="Trial Balance"
menu="False"
report_type="qweb-pdf" 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 <report
id="action_report_trial_balance_html" id="action_report_trial_balance_html"
model="report_trial_balance"
model="trial.balance.report.wizard"
string="Trial Balance" string="Trial Balance"
menu="False"
report_type="qweb-html" 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 --> <!-- Open Items -->
<report <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" string="Open Items"
menu="False"
report_type="qweb-pdf" 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 <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" string="Open Items"
menu="False"
report_type="qweb-html" 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 --> <!-- Aged Partner Balance -->
<report <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" string="Aged Partner Balance"
report_type="qweb-pdf" 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 <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" string="Aged Partner Balance"
report_type="qweb-html" 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 --> <!-- VAT Report -->
<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" string="VAT Report"
report_type="qweb-pdf" 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 <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" string="VAT Report"
report_type="qweb-html" 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 --> <!-- PDF REPORTS : paperformat -->
<record id="report_qweb_paperformat" model="report.paperformat"> <record id="report_qweb_paperformat" model="report.paperformat">
@ -129,7 +139,11 @@
<field name="dpi">110</field> <field name="dpi">110</field>
</record> </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"/> <field name="paperformat_id" ref="report_qweb_paperformat"/>
</record> </record>
@ -137,17 +151,15 @@
<field name="paperformat_id" ref="report_qweb_paperformat"/> <field name="paperformat_id" ref="report_qweb_paperformat"/>
</record> </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"/> <field name="paperformat_id" ref="report_qweb_paperformat"/>
</record> </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"/> <field name="paperformat_id" ref="report_qweb_paperformat"/>
</record> </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"/> <field name="paperformat_id" ref="report_qweb_paperformat"/>
</record> </record>
@ -155,7 +167,7 @@
<record id="action_report_general_ledger_xlsx" model="ir.actions.report"> <record id="action_report_general_ledger_xlsx" model="ir.actions.report">
<field name="name">General Ledger XLSX</field> <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="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_general_ledger_xlsx</field> <field name="report_name">a_f_r.report_general_ledger_xlsx</field>
<field name="report_type">xlsx</field> <field name="report_type">xlsx</field>
@ -164,7 +176,7 @@
<record id="action_report_journal_ledger_xlsx" model="ir.actions.report"> <record id="action_report_journal_ledger_xlsx" model="ir.actions.report">
<field name="name">Journal Ledger XLSX</field> <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="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_journal_ledger_xlsx</field> <field name="report_name">a_f_r.report_journal_ledger_xlsx</field>
<field name="report_type">xlsx</field> <field name="report_type">xlsx</field>
@ -173,7 +185,7 @@
<record id="action_report_trial_balance_xlsx" model="ir.actions.report"> <record id="action_report_trial_balance_xlsx" model="ir.actions.report">
<field name="name">Trial Balance XLSX</field> <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="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_trial_balance_xlsx</field> <field name="report_name">a_f_r.report_trial_balance_xlsx</field>
<field name="report_type">xlsx</field> <field name="report_type">xlsx</field>
@ -182,7 +194,7 @@
<record id="action_report_open_items_xlsx" model="ir.actions.report"> <record id="action_report_open_items_xlsx" model="ir.actions.report">
<field name="name">Open Items XLSX</field> <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="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_open_items_xlsx</field> <field name="report_name">a_f_r.report_open_items_xlsx</field>
<field name="report_type">xlsx</field> <field name="report_type">xlsx</field>
@ -191,16 +203,16 @@
<record id="action_report_aged_partner_balance_xlsx" model="ir.actions.report"> <record id="action_report_aged_partner_balance_xlsx" model="ir.actions.report">
<field name="name">Aged Partner Balance XLSX</field> <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="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_aged_partner_balance_xlsx</field> <field name="report_name">a_f_r.report_aged_partner_balance_xlsx</field>
<field name="report_type">xlsx</field> <field name="report_type">xlsx</field>
<field name="report_file">report_aged_partner_balance</field> <field name="report_file">report_aged_partner_balance</field>
</record> </record>
<record id="action_report_vat_report_xlsx" model="ir.actions.report"> <record id="action_report_vat_report_xlsx" model="ir.actions.report">
<field name="name">VAT Report XLSX</field> <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="type">ir.actions.report</field>
<field name="report_name">a_f_r.report_vat_report_xlsx</field> <field name="report_name">a_f_r.report_vat_report_xlsx</field>
<field name="report_type">xlsx</field> <field name="report_type">xlsx</field>

4
account_financial_report/tests/__init__.py

@ -2,10 +2,6 @@
# © 2016 Julien Coux (Camptocamp) # © 2016 Julien Coux (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).- # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-
from . 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_general_ledger
from . import test_journal_ledger from . import test_journal_ledger
from . import test_open_items 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 # Author: Julien Coux
# Copyright 2016 Camptocamp SA # 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). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import time import time
from odoo.tests import common from odoo.tests import common
from odoo import fields
from odoo import fields, api
from datetime import date 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): class TestGeneralLedgerReport(common.TransactionCase):
@ -106,6 +31,7 @@ class TestGeneralLedgerReport(common.TransactionCase):
'=', '=',
self.env.ref('account.data_unaffected_earnings').id self.env.ref('account.data_unaffected_earnings').id
)], limit=1) )], limit=1)
self.partner = self.env.ref('base.res_partner_12')
def _add_move( def _add_move(
self, self,
@ -148,47 +74,92 @@ class TestGeneralLedgerReport(common.TransactionCase):
move.post() move.post()
def _get_report_lines(self, with_partners=False): def _get_report_lines(self, with_partners=False):
centralize = True
if with_partners:
centralize = False
company = self.env.ref('base.main_company') 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_from': self.fy_date_start,
'date_to': self.fy_date_end, 'date_to': self.fy_date_end,
'only_posted_moves': True,
'target_move': 'posted',
'hide_account_at_0': False, 'hide_account_at_0': False,
'company_id': company.id, 'company_id': company.id,
'fy_start_date': self.fy_date_start, 'fy_start_date': self.fy_date_start,
'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): def test_01_account_balance(self):
# Generate the general ledger line # 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 # Add a move at the previous day of the first day of fiscal year
# to check the initial balance # to check the initial balance
@ -201,17 +172,27 @@ class TestGeneralLedgerReport(common.TransactionCase):
) )
# Re Generate the general ledger line # 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 # 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 # Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used # 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 # 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 # 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 # Add another move at the end day of fiscal year
# to check that it correctly used on report # to check that it correctly used on report
@ -255,29 +250,46 @@ class TestGeneralLedgerReport(common.TransactionCase):
) )
# Re Generate the general ledger line # 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 # 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): def test_02_partner_balance(self):
# Generate the general ledger line # 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 # Add a move at the previous day of the first day of fiscal year
# to check the initial balance # to check the initial balance
@ -290,16 +302,26 @@ class TestGeneralLedgerReport(common.TransactionCase):
) )
# Re Generate the general ledger line # 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 # 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 # Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used # 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 # 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 # 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 # Add another move at the end day of fiscal year
# to check that it correctly used on report # to check that it correctly used on report
@ -335,29 +367,47 @@ class TestGeneralLedgerReport(common.TransactionCase):
) )
# Re Generate the general ledger line # 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 # 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): def test_03_unaffected_account_balance(self):
# Generate the general ledger line # 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 # 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 # Add a move at the previous day of the first day of fiscal year
# to check the initial balance # to check the initial balance
@ -370,16 +420,24 @@ class TestGeneralLedgerReport(common.TransactionCase):
) )
# Re Generate the general ledger line # 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 # 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 # Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used # 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 # 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 # 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 # Add another move at the end day of fiscal year
# to check that it correctly used on report # to check that it correctly used on report
@ -419,29 +485,45 @@ class TestGeneralLedgerReport(common.TransactionCase):
) )
# Re Generate the general ledger line # 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 # 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): def test_04_unaffected_account_balance_2_years(self):
# Generate the general ledger line # 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 # 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 # Add a move at any date 2 years before the balance
# (to create an historic) # (to create an historic)
@ -454,16 +536,24 @@ class TestGeneralLedgerReport(common.TransactionCase):
) )
# Re Generate the general ledger line # 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 # 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 # Affect the company's result last year
self._add_move( self._add_move(
@ -486,17 +576,26 @@ class TestGeneralLedgerReport(common.TransactionCase):
unaffected_debit=0, unaffected_debit=0,
unaffected_credit=0 unaffected_credit=0
) )
# Re Generate the general ledger line # 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 # 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): def test_partner_filter(self):
partner_1 = self.env.ref('base.res_partner_1') 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 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). # 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 dateutil.relativedelta import relativedelta
from odoo.fields import Date from odoo.fields import Date
from odoo.tests.common import TransactionCase 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): class TestJournalReport(TransactionCase):
@ -86,11 +16,13 @@ class TestJournalReport(TransactionCase):
self.AccountObj = self.env['account.account'] self.AccountObj = self.env['account.account']
self.InvoiceObj = self.env['account.invoice'] self.InvoiceObj = self.env['account.invoice']
self.JournalObj = self.env['account.journal'] self.JournalObj = self.env['account.journal']
self.JournalReportObj = self.env['journal.ledger.report.wizard']
self.MoveObj = self.env['account.move'] self.MoveObj = self.env['account.move']
self.ReportJournalLedger = self.env['report_journal_ledger']
self.TaxObj = self.env['account.tax'] 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') self.company = self.env.ref('base.main_company')
today = datetime.today() today = datetime.today()
@ -191,52 +123,50 @@ class TestJournalReport(TransactionCase):
return self.MoveObj.create(move_vals) return self.MoveObj.create(move_vals)
def check_report_journal_debit_credit( def check_report_journal_debit_credit(
self, report, expected_debit, expected_credit):
self, res_data, expected_debit, expected_credit):
self.assertEqual( self.assertEqual(
expected_debit, 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( self.assertEqual(
expected_credit, 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( def check_report_journal_debit_credit_taxes(
self, report,
self, res_data,
expected_base_debit, expected_base_credit, expected_base_debit, expected_base_credit,
expected_tax_debit, expected_tax_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): def test_01_test_total(self):
today_date = Date.today() today_date = Date.today()
@ -250,42 +180,43 @@ class TestJournalReport(TransactionCase):
last_year_date, self.journal_sale, last_year_date, self.journal_sale,
0, 100, 100, 0) 0, 100, 100, 0)
report = self.ReportJournalLedger.create({
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start, 'date_from': self.fy_date_start,
'date_to': self.fy_date_end, 'date_to': self.fy_date_end,
'company_id': self.company.id, 'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)] '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( move3 = self._add_move(
today_date, self.journal_sale, today_date, self.journal_sale,
0, 100, 100, 0) 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() 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() 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() 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): def test_02_test_taxes_out_invoice(self):
invoice_values = { invoice_values = {
@ -314,16 +245,16 @@ class TestJournalReport(TransactionCase):
invoice = self.InvoiceObj.create(invoice_values) invoice = self.InvoiceObj.create(invoice_values)
invoice.action_invoice_open() invoice.action_invoice_open()
report = self.ReportJournalLedger.create({
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start, 'date_from': self.fy_date_start,
'date_to': self.fy_date_end, 'date_to': self.fy_date_end,
'company_id': self.company.id, 'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)] '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): def test_03_test_taxes_in_invoice(self):
invoice_values = { invoice_values = {
@ -352,13 +283,14 @@ class TestJournalReport(TransactionCase):
invoice = self.InvoiceObj.create(invoice_values) invoice = self.InvoiceObj.create(invoice_values)
invoice.action_invoice_open() invoice.action_invoice_open()
report = self.ReportJournalLedger.create({
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start, 'date_from': self.fy_date_start,
'date_to': self.fy_date_end, 'date_to': self.fy_date_end,
'company_id': self.company.id, 'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)] '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 # Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import 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): def test_partner_filter(self):
partner_1 = self.env.ref('base.res_partner_1') 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 # Author: Julien Coux
# Copyright 2016 Camptocamp SA # 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). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from datetime import date
from odoo.tests import common 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): class TestTrialBalanceReport(common.TransactionCase):
@ -114,6 +58,13 @@ class TestTrialBalanceReport(common.TransactionCase):
self.fy_date_end = '2016-12-31' self.fy_date_end = '2016-12-31'
self.date_start = '2016-01-01' self.date_start = '2016-01-01'
self.date_end = '2016-12-31' 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( def _add_move(
self, self,
@ -169,49 +120,81 @@ class TestTrialBalanceReport(common.TransactionCase):
def _get_report_lines(self, with_partners=False, hierarchy_on='computed'): def _get_report_lines(self, with_partners=False, hierarchy_on='computed'):
company = self.env.ref('base.main_company') 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_from': self.date_start,
'date_to': self.date_end, '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, 'hierarchy_on': hierarchy_on,
'company_id': company.id, 'company_id': company.id,
'fy_start_date': self.fy_date_start, 'fy_start_date': self.fy_date_start,
'show_partner_details': with_partners, '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 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): def test_00_account_group(self):
self.assertGreaterEqual(len(self.group1.compute_account_ids), 19) self.assertGreaterEqual(len(self.group1.compute_account_ids), 19)
self.assertGreaterEqual(len(self.group2.compute_account_ids), 9) 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'): if acc.code.startswith('1') or acc.code.startswith('2'):
acc.code = '999' + acc.code acc.code = '999' + acc.code
# Generate the general ledger line # 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 # Add a move at the previous day of the first day of fiscal year
# to check the initial balance # to check the initial balance
@ -242,20 +231,29 @@ class TestTrialBalanceReport(common.TransactionCase):
) )
# Re Generate the trial balance line # 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 # 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 # Add reversed move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used # 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 # 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 # 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 # Add another move at the end day of fiscal year
# to check that it correctly used on report # to check that it correctly used on report
@ -305,37 +315,53 @@ class TestTrialBalanceReport(common.TransactionCase):
) )
# Re Generate the trial balance line # 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 # 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): def test_02_account_balance_hierarchy(self):
# Generate the general ledger line # 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 # Add a move at the previous day of the first day of fiscal year
# to check the initial balance # to check the initial balance
@ -348,20 +374,29 @@ class TestTrialBalanceReport(common.TransactionCase):
) )
# Re Generate the trial balance line # 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 # 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 # Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used # 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 # 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 # 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 # Add another move at the end day of fiscal year
# to check that it correctly used on report # to check that it correctly used on report
self._add_move( self._add_move(
@ -411,35 +458,50 @@ class TestTrialBalanceReport(common.TransactionCase):
) )
# Re Generate the trial balance line # 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 # 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): def test_03_partner_balance(self):
# Generate the trial balance line # 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 # Add a move at the previous day of the first day of fiscal year
# to check the initial balance # to check the initial balance
@ -452,14 +514,20 @@ class TestTrialBalanceReport(common.TransactionCase):
) )
# Re Generate the trial balance line # 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 # 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 # Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used # 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 # 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 # 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 # Add another move at the end day of fiscal year
# to check that it correctly used on report # to check that it correctly used on report
@ -493,14 +567,20 @@ class TestTrialBalanceReport(common.TransactionCase):
) )
# Re Generate the trial balance line # 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 # 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): def test_04_undistributed_pl(self):
# Add a P&L Move in the previous FY # 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 = self.env['account.move'].create(move_vals)
move.post() move.post()
# Generate the trial balance line # Generate the trial balance line
report_account_model = self.env['report_trial_balance_account']
company = self.env.ref('base.main_company') 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_from': self.date_start,
'date_to': self.date_end, 'date_to': self.date_end,
'only_posted_moves': True,
'target_move': 'posted',
'hide_account_at_0': False, 'hide_account_at_0': False,
'hierarchy_on': 'none', 'hierarchy_on': 'none',
'company_id': company.id, 'company_id': company.id,
'fy_start_date': self.fy_date_start, '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 # Add a P&L Move to the current FY
move_name = 'current year pl move' move_name = 'current year pl move'
journal = self.env['account.journal'].search([], limit=1) 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 = self.env['account.move'].create(move_vals)
move.post() move.post()
# Re Generate the trial balance line # 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_from': self.date_start,
'date_to': self.date_end, 'date_to': self.date_end,
'only_posted_moves': True,
'target_move': 'posted',
'hide_account_at_0': False, 'hide_account_at_0': False,
'hierarchy_on': 'none', 'hierarchy_on': 'none',
'company_id': company.id, 'company_id': company.id,
'fy_start_date': self.fy_date_start, '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 # The unaffected earnings account is not affected by a journal entry
# made to the P&L in the current fiscal year. # 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 # Add a Move including Unaffected Earnings to the current FY
move_name = 'current year unaffected earnings move' move_name = 'current year unaffected earnings move'
journal = self.env['account.journal'].search([], limit=1) 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 = self.env['account.move'].create(move_vals)
move.post() move.post()
# Re Generate the trial balance line # 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_from': self.date_start,
'date_to': self.date_end, 'date_to': self.date_end,
'only_posted_moves': True,
'target_move': 'posted',
'hide_account_at_0': False, 'hide_account_at_0': False,
'hierarchy_on': 'none', 'hierarchy_on': 'none',
'company_id': company.id, 'company_id': company.id,
'fy_start_date': self.fy_date_start, '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 # The unaffected earnings account affected by a journal entry
# made to the unaffected earnings in the current fiscal year. # 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 # 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 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). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import time import time
from datetime import date from datetime import date
from odoo.tests import common 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): class TestVATReport(common.TransactionCase):
@ -155,106 +118,142 @@ class TestVATReport(common.TransactionCase):
self.cbinvoice.compute_taxes() self.cbinvoice.compute_taxes()
self.cbinvoice.action_invoice_open() self.cbinvoice.action_invoice_open()
def _get_report_lines(self):
self.cbinvoice.pay_and_reconcile( self.cbinvoice.pay_and_reconcile(
self.bank_journal.id, 300, date( self.bank_journal.id, 300, date(
date.today().year, date.today().month, 10)) 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_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'company_id': self.company.id, 'company_id': self.company.id,
'based_on': 'taxtags',
'based_on': based_on,
'tax_detail': True, '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): def test_01_compute(self):
# Generate the vat lines # 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 # 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 # 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): def test_wizard_date_range(self):
vat_wizard = self.env['vat.report.wizard'] vat_wizard = self.env['vat.report.wizard']

20
account_financial_report/view/report_template.xml

@ -6,7 +6,7 @@
<xpath expr="." position="inside"> <xpath expr="." position="inside">
<link href="/account_financial_report/static/src/css/report.css" rel="stylesheet"/> <link href="/account_financial_report/static/src/css/report.css" rel="stylesheet"/>
<script type="text/javascript" <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" <script type="text/javascript"
src="/account_financial_report/static/src/js/account_financial_report_widgets.js"/> src="/account_financial_report/static/src/js/account_financial_report_widgets.js"/>
</xpath> </xpath>
@ -22,37 +22,37 @@
<record id="action_report_general_ledger" model="ir.actions.client"> <record id="action_report_general_ledger" model="ir.actions.client">
<field name="name">General Ledger</field> <field name="name">General Ledger</field>
<field name="tag">account_financial_report_backend</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>
<record id="action_report_journal_ledger" model="ir.actions.client"> <record id="action_report_journal_ledger" model="ir.actions.client">
<field name="name">Journal</field> <field name="name">Journal</field>
<field name="tag">account_financial_report_backend</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>
<record id="action_report_open_items" model="ir.actions.client"> <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>
<record id="action_report_trial_balance" model="ir.actions.client"> <record id="action_report_trial_balance" model="ir.actions.client">
<field name="name">Trial Balance</field> <field name="name">Trial Balance</field>
<field name="tag">account_financial_report_backend</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>
<record id="action_report_aged_partner_balance" model="ir.actions.client"> <record id="action_report_aged_partner_balance" model="ir.actions.client">
<field name="name">Aged Partner Balance</field> <field name="name">Aged Partner Balance</field>
<field name="tag">account_financial_report_backend</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>
<record id="action_report_vat_report" model="ir.actions.client"> <record id="action_report_vat_report" model="ir.actions.client">
<field name="name">VAT Report</field> <field name="name">VAT Report</field>
<field name="tag">account_financial_report_backend</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> </record>
</odoo> </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). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models from odoo import api, fields, models
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
class AgedPartnerBalanceWizard(models.TransientModel): class AgedPartnerBalanceWizard(models.TransientModel):
"""Aged partner balance report wizard.""" """Aged partner balance report wizard."""
_name = 'aged.partner.balance.wizard'
_name = 'aged.partner.balance.report.wizard'
_description = 'Aged Partner Balance Wizard' _description = 'Aged Partner Balance Wizard'
_inherit = 'account_financial_report_abstract_wizard' _inherit = 'account_financial_report_abstract_wizard'
@ -66,35 +64,36 @@ class AgedPartnerBalanceWizard(models.TransientModel):
@api.onchange('receivable_accounts_only', 'payable_accounts_only') @api.onchange('receivable_accounts_only', 'payable_accounts_only')
def onchange_type_accounts_only(self): def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change.""" """Handle receivable/payable accounts only change."""
domain = [('company_id', '=', self.company_id.id)]
if self.receivable_accounts_only or self.payable_accounts_only: 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: if self.receivable_accounts_only and self.payable_accounts_only:
domain += [('internal_type', 'in', ('receivable', 'payable'))] domain += [('internal_type', 'in', ('receivable', 'payable'))]
elif self.receivable_accounts_only: elif self.receivable_accounts_only:
domain += [('internal_type', '=', 'receivable')] domain += [('internal_type', '=', 'receivable')]
elif self.payable_accounts_only: elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')] 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: 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 @api.multi
def button_export_html(self): def button_export_html(self):
self.ensure_one() 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 @api.multi
def button_export_pdf(self): def button_export_pdf(self):
@ -111,17 +110,15 @@ class AgedPartnerBalanceWizard(models.TransientModel):
def _prepare_report_aged_partner_balance(self): def _prepare_report_aged_partner_balance(self):
self.ensure_one() self.ensure_one()
return { return {
'wizard_id': self.id,
'date_at': self.date_at, 'date_at': self.date_at,
'only_posted_moves': self.target_move == 'posted', 'only_posted_moves': self.target_move == 'posted',
'company_id': self.company_id.id, '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, 'show_move_line_details': self.show_move_line_details,
} }
def _export(self, report_type): def _export(self, report_type):
"""Default export is PDF.""" """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 --> <!-- AGED PARTNER BALANCE -->
<record id="aged_partner_balance_wizard" model="ir.ui.view"> <record id="aged_partner_balance_wizard" model="ir.ui.view">
<field name="name">Aged Partner Balance</field> <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"> <field name="arch" type="xml">
<form> <form>
<group name="main_info"> <group name="main_info">
@ -50,7 +50,7 @@
<act_window id="action_aged_partner_balance_wizard" <act_window id="action_aged_partner_balance_wizard"
name="Aged Partner Balance" name="Aged Partner Balance"
res_model="aged.partner.balance.wizard"
res_model="aged.partner.balance.report.wizard"
view_type="form" view_type="form"
view_mode="form" view_mode="form"
view_id="aged_partner_balance_wizard" 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 import api, fields, models, _
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
import time import time
@ -203,22 +201,42 @@ class GeneralLedgerReportWizard(models.TransientModel):
else: 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_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 @api.multi
def button_export_html(self): def button_export_html(self):
self.ensure_one() 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 @api.multi
def button_export_pdf(self): def button_export_pdf(self):
@ -235,6 +253,7 @@ class GeneralLedgerReportWizard(models.TransientModel):
def _prepare_report_general_ledger(self): def _prepare_report_general_ledger(self):
self.ensure_one() self.ensure_one()
return { return {
'wizard_id': self.id,
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted', 'only_posted_moves': self.target_move == 'posted',
@ -242,18 +261,22 @@ class GeneralLedgerReportWizard(models.TransientModel):
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'show_analytic_tags': self.show_analytic_tags, 'show_analytic_tags': self.show_analytic_tags,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'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, 'centralize': self.centralize,
'fy_start_date': self.fy_start_date, 'fy_start_date': self.fy_start_date,
'unaffected_earnings_account': self.unaffected_earnings_account.id,
} }
def _export(self, report_type): def _export(self, report_type):
"""Default export is PDF.""" """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). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _ from odoo import api, fields, models, _
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
class JournalLedgerReportWizard(models.TransientModel): class JournalLedgerReportWizard(models.TransientModel):
@ -102,26 +100,27 @@ class JournalLedgerReportWizard(models.TransientModel):
('company_id', '=', self.company_id.id)] ('company_id', '=', self.company_id.id)]
return res 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 @api.multi
def button_export_html(self): def button_export_html(self):
self.ensure_one() 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 @api.multi
def button_export_pdf(self): def button_export_pdf(self):
self.ensure_one()
report_type = 'qweb-pdf' report_type = 'qweb-pdf'
return self._export(report_type) return self._export(report_type)
@ -140,12 +139,13 @@ class JournalLedgerReportWizard(models.TransientModel):
journals = self.env['account.journal'].search( journals = self.env['account.journal'].search(
[('company_id', '=', self.company_id.id)]) [('company_id', '=', self.company_id.id)])
return { return {
'wizard_id': self.id,
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'move_target': self.move_target, 'move_target': self.move_target,
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'journal_ids': [(6, 0, journals.ids)],
'journal_ids': journals.ids,
'sort_option': self.sort_option, 'sort_option': self.sort_option,
'group_option': self.group_option, 'group_option': self.group_option,
'with_account_name': self.with_account_name, 'with_account_name': self.with_account_name,
@ -154,7 +154,44 @@ class JournalLedgerReportWizard(models.TransientModel):
def _export(self, report_type): def _export(self, report_type):
"""Default export is PDF.""" """Default export is PDF."""
self.ensure_one() 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). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api from odoo import models, fields, api
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
class OpenItemsReportWizard(models.TransientModel): class OpenItemsReportWizard(models.TransientModel):
@ -23,6 +21,7 @@ class OpenItemsReportWizard(models.TransientModel):
) )
date_at = fields.Date(required=True, date_at = fields.Date(required=True,
default=fields.Date.context_today) default=fields.Date.context_today)
date_from = fields.Date(string='Date From')
target_move = fields.Selection([('posted', 'All Posted Entries'), target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')], ('all', 'All Entries')],
string='Target Moves', string='Target Moves',
@ -84,35 +83,36 @@ class OpenItemsReportWizard(models.TransientModel):
@api.onchange('receivable_accounts_only', 'payable_accounts_only') @api.onchange('receivable_accounts_only', 'payable_accounts_only')
def onchange_type_accounts_only(self): def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change.""" """Handle receivable/payable accounts only change."""
domain = [('company_id', '=', self.company_id.id)]
if self.receivable_accounts_only or self.payable_accounts_only: 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: if self.receivable_accounts_only and self.payable_accounts_only:
domain += [('internal_type', 'in', ('receivable', 'payable'))] domain += [('internal_type', 'in', ('receivable', 'payable'))]
elif self.receivable_accounts_only: elif self.receivable_accounts_only:
domain += [('internal_type', '=', 'receivable')] domain += [('internal_type', '=', 'receivable')]
elif self.payable_accounts_only: elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')] 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: 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 @api.multi
def button_export_html(self): def button_export_html(self):
self.ensure_one() 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 @api.multi
def button_export_pdf(self): def button_export_pdf(self):
@ -129,18 +129,17 @@ class OpenItemsReportWizard(models.TransientModel):
def _prepare_report_open_items(self): def _prepare_report_open_items(self):
self.ensure_one() self.ensure_one()
return { 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', 'only_posted_moves': self.target_move == 'posted',
'hide_account_at_0': self.hide_account_at_0, 'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_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): 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="filters">
<group name="date_range"> <group name="date_range">
<field name="date_at"/> <field name="date_at"/>
<field name="date_from"/>
</group> </group>
<group name="other_filters"> <group name="other_filters">
<field name="target_move" widget="radio"/> <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). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models, _ 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 from odoo.exceptions import UserError, ValidationError
@ -41,7 +39,7 @@ class TrialBalanceReportWizard(models.TransientModel):
('none', 'No hierarchy')], ('none', 'No hierarchy')],
string='Hierarchy On', string='Hierarchy On',
required=True, required=True,
default='computed',
default='none',
help="""Computed Accounts: Use when the account group have codes help="""Computed Accounts: Use when the account group have codes
that represent prefixes of the actual accounts.\n that represent prefixes of the actual accounts.\n
Child Accounts: Use when your account groups are hierarchical.\n Child Accounts: Use when your account groups are hierarchical.\n
@ -183,25 +181,45 @@ class TrialBalanceReportWizard(models.TransientModel):
if self.show_partner_details: if self.show_partner_details:
self.receivable_accounts_only = self.payable_accounts_only = True self.receivable_accounts_only = self.payable_accounts_only = True
else: 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 @api.multi
def button_export_html(self): def button_export_html(self):
self.ensure_one() 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 @api.multi
def button_export_pdf(self): def button_export_pdf(self):
@ -218,26 +236,25 @@ class TrialBalanceReportWizard(models.TransientModel):
def _prepare_report_trial_balance(self): def _prepare_report_trial_balance(self):
self.ensure_one() self.ensure_one()
return { return {
'wizard_id': self.id,
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted', 'only_posted_moves': self.target_move == 'posted',
'hide_account_at_0': self.hide_account_at_0, 'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency, 'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'filter_account_ids': [(6, 0, self.account_ids.ids)],
'filter_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, 'fy_start_date': self.fy_start_date,
'hierarchy_on': self.hierarchy_on, 'hierarchy_on': self.hierarchy_on,
'limit_hierarchy_level': self.limit_hierarchy_level, 'limit_hierarchy_level': self.limit_hierarchy_level,
'show_hierarchy_level': self.show_hierarchy_level, 'show_hierarchy_level': self.show_hierarchy_level,
'hide_parent_hierarchy_level': self.hide_parent_hierarchy_level, 'hide_parent_hierarchy_level': self.hide_parent_hierarchy_level,
'show_partner_details': self.show_partner_details, 'show_partner_details': self.show_partner_details,
'unaffected_earnings_account': self.unaffected_earnings_account.id,
} }
def _export(self, report_type): def _export(self, report_type):
"""Default export is PDF.""" """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="hide_account_at_0"/>
<field name="show_partner_details"/> <field name="show_partner_details"/>
<field name="hierarchy_on" widget="radio" attrs="{'invisible':[('show_partner_details','=',True)]}"/> <field name="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="show_hierarchy_level" attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"/>
<field name="hide_parent_hierarchy_level" attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"/> <field name="hide_parent_hierarchy_level" attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"/>
<field name="foreign_currency"/> <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). # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models, _ from odoo import api, fields, models, _
from odoo.tools.safe_eval import safe_eval
from odoo.tools import pycompat
from odoo.exceptions import ValidationError from odoo.exceptions import ValidationError
@ -62,22 +60,24 @@ class VATReportWizard(models.TransientModel):
_('The Company in the Vat Report Wizard and in ' _('The Company in the Vat Report Wizard and in '
'Date Range must be the same.')) '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 @api.multi
def button_export_html(self): def button_export_html(self):
self.ensure_one() 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 @api.multi
def button_export_pdf(self): def button_export_pdf(self):
@ -94,6 +94,7 @@ class VATReportWizard(models.TransientModel):
def _prepare_vat_report(self): def _prepare_vat_report(self):
self.ensure_one() self.ensure_one()
return { return {
'wizard_id': self.id,
'company_id': self.company_id.id, 'company_id': self.company_id.id,
'date_from': self.date_from, 'date_from': self.date_from,
'date_to': self.date_to, 'date_to': self.date_to,
@ -103,7 +104,4 @@ class VATReportWizard(models.TransientModel):
def _export(self, report_type): def _export(self, report_type):
"""Default export is PDF.""" """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