Browse Source

[IMP] account_financial_report: black, isort

pull/749/head
Ernesto Tejeda 5 years ago
committed by João Marques
parent
commit
fabb420365
  1. 1
      account_financial_report/__init__.py
  2. 86
      account_financial_report/__manifest__.py
  3. 24
      account_financial_report/menuitems.xml
  4. 11
      account_financial_report/models/account.py
  5. 60
      account_financial_report/models/account_group.py
  6. 15
      account_financial_report/models/account_move_line.py
  7. 449
      account_financial_report/report/abstract_report_xlsx.py
  8. 538
      account_financial_report/report/aged_partner_balance.py
  9. 338
      account_financial_report/report/aged_partner_balance_xlsx.py
  10. 846
      account_financial_report/report/general_ledger.py
  11. 353
      account_financial_report/report/general_ledger_xlsx.py
  12. 362
      account_financial_report/report/journal_ledger.py
  13. 295
      account_financial_report/report/journal_ledger_xlsx.py
  14. 390
      account_financial_report/report/open_items.py
  15. 176
      account_financial_report/report/open_items_xlsx.py
  16. 589
      account_financial_report/report/templates/aged_partner_balance.xml
  17. 707
      account_financial_report/report/templates/general_ledger.xml
  18. 572
      account_financial_report/report/templates/journal_ledger.xml
  19. 24
      account_financial_report/report/templates/layouts.xml
  20. 181
      account_financial_report/report/templates/open_items.xml
  21. 1184
      account_financial_report/report/templates/trial_balance.xml
  22. 218
      account_financial_report/report/templates/vat_report.xml
  23. 963
      account_financial_report/report/trial_balance.py
  24. 342
      account_financial_report/report/trial_balance_xlsx.py
  25. 205
      account_financial_report/report/vat_report.py
  26. 45
      account_financial_report/report/vat_report_xlsx.py
  27. 202
      account_financial_report/reports.xml
  28. 74
      account_financial_report/static/src/css/report.css
  29. 77
      account_financial_report/static/src/js/account_financial_report_backend.js
  30. 96
      account_financial_report/static/src/js/account_financial_report_widgets.js
  31. 1
      account_financial_report/tests/__init__.py
  32. 635
      account_financial_report/tests/test_general_ledger.py
  33. 426
      account_financial_report/tests/test_journal_ledger.py
  34. 22
      account_financial_report/tests/test_open_items.py
  35. 917
      account_financial_report/tests/test_trial_balance.py
  36. 398
      account_financial_report/tests/test_vat_report.py
  37. 6
      account_financial_report/view/account_view.xml
  38. 6
      account_financial_report/view/report_aged_partner_balance.xml
  39. 6
      account_financial_report/view/report_general_ledger.xml
  40. 6
      account_financial_report/view/report_journal_ledger.xml
  41. 6
      account_financial_report/view/report_open_items.xml
  42. 83
      account_financial_report/view/report_template.xml
  43. 8
      account_financial_report/view/report_trial_balance.xml
  44. 6
      account_financial_report/view/report_vat_report.xml
  45. 29
      account_financial_report/wizard/abstract_wizard.py
  46. 99
      account_financial_report/wizard/aged_partner_balance_wizard.py
  47. 82
      account_financial_report/wizard/aged_partner_balance_wizard_view.xml
  48. 275
      account_financial_report/wizard/general_ledger_wizard.py
  49. 159
      account_financial_report/wizard/general_ledger_wizard_view.xml
  50. 146
      account_financial_report/wizard/journal_ledger_wizard.py
  51. 82
      account_financial_report/wizard/journal_ledger_wizard_view.xml
  52. 130
      account_financial_report/wizard/open_items_wizard.py
  53. 107
      account_financial_report/wizard/open_items_wizard_view.xml
  54. 264
      account_financial_report/wizard/trial_balance_wizard.py
  55. 164
      account_financial_report/wizard/trial_balance_wizard_view.xml
  56. 101
      account_financial_report/wizard/vat_report_wizard.py
  57. 75
      account_financial_report/wizard/vat_report_wizard_view.xml

1
account_financial_report/__init__.py

@ -1,4 +1,3 @@
# Author: Damien Crier
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).

86
account_financial_report/__manifest__.py

@ -4,53 +4,45 @@
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
{
'name': 'Account Financial Reports',
'version': '12.0.2.0.0',
'category': 'Reporting',
'summary': 'OCA Financial Reports',
'author': 'Camptocamp SA,'
'initOS GmbH,'
'redCOR AG,'
'ForgeFlow,'
'Odoo Community Association (OCA)',
"name": "Account Financial Reports",
"version": "12.0.2.0.0",
"category": "Reporting",
"summary": "OCA Financial Reports",
"author": "Camptocamp SA,"
"initOS GmbH,"
"redCOR AG,"
"ForgeFlow,"
"Odoo Community Association (OCA)",
"website": "https://odoo-community.org/",
'depends': [
'account',
'date_range',
'report_xlsx',
"depends": ["account", "date_range", "report_xlsx",],
"data": [
"wizard/aged_partner_balance_wizard_view.xml",
"wizard/general_ledger_wizard_view.xml",
"wizard/journal_ledger_wizard_view.xml",
"wizard/open_items_wizard_view.xml",
"wizard/trial_balance_wizard_view.xml",
"wizard/vat_report_wizard_view.xml",
"menuitems.xml",
"reports.xml",
"report/templates/layouts.xml",
"report/templates/aged_partner_balance.xml",
"report/templates/general_ledger.xml",
"report/templates/journal_ledger.xml",
"report/templates/open_items.xml",
"report/templates/trial_balance.xml",
"report/templates/vat_report.xml",
"view/account_view.xml",
"view/report_template.xml",
"view/report_general_ledger.xml",
"view/report_journal_ledger.xml",
"view/report_trial_balance.xml",
"view/report_open_items.xml",
"view/report_aged_partner_balance.xml",
"view/report_vat_report.xml",
],
'data': [
'wizard/aged_partner_balance_wizard_view.xml',
'wizard/general_ledger_wizard_view.xml',
'wizard/journal_ledger_wizard_view.xml',
'wizard/open_items_wizard_view.xml',
'wizard/trial_balance_wizard_view.xml',
'wizard/vat_report_wizard_view.xml',
'menuitems.xml',
'reports.xml',
'report/templates/layouts.xml',
'report/templates/aged_partner_balance.xml',
'report/templates/general_ledger.xml',
'report/templates/journal_ledger.xml',
'report/templates/open_items.xml',
'report/templates/trial_balance.xml',
'report/templates/vat_report.xml',
'view/account_view.xml',
'view/report_template.xml',
'view/report_general_ledger.xml',
'view/report_journal_ledger.xml',
'view/report_trial_balance.xml',
'view/report_open_items.xml',
'view/report_aged_partner_balance.xml',
'view/report_vat_report.xml',
],
"external_dependencies": {
"python": ['natsort',
'pandas',
],
},
'installable': True,
'application': True,
'auto_install': False,
'license': 'AGPL-3',
"external_dependencies": {"python": ["natsort", "pandas",],},
"installable": True,
"application": True,
"auto_install": False,
"license": "AGPL-3",
}

24
account_financial_report/menuitems.xml

@ -1,53 +1,45 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<menuitem
parent="account.menu_finance_reports"
id="menu_oca_reports"
name="OCA accounting reports"
groups="account.group_account_manager,account.group_account_user"
/>
/>
<menuitem
parent="menu_oca_reports"
action="action_general_ledger_wizard"
id="menu_general_ledger_wizard"
sequence="10"
/>
/>
<menuitem
parent="menu_oca_reports"
action="action_journal_ledger_wizard"
id="menu_journal_ledger_wizard"
sequence="15"
/>
/>
<menuitem
parent="menu_oca_reports"
action="action_trial_balance_wizard"
id="menu_trial_balance_wizard"
sequence="20"
/>
/>
<menuitem
parent="menu_oca_reports"
action="action_open_items_wizard"
id="menu_open_items_wizard"
sequence="30"
/>
/>
<menuitem
parent="menu_oca_reports"
action="action_aged_partner_balance_wizard"
id="menu_aged_partner_balance_wizard"
sequence="40"
/>
/>
<menuitem
parent="menu_oca_reports"
action="action_vat_report_wizard"
id="menu_vat_report_wizard"
sequence="50"
/>
/>
</odoo>

11
account_financial_report/models/account.py

@ -1,13 +1,14 @@
# © 2011 Guewen Baconnier (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-
from odoo import models, fields
from odoo import fields, models
class AccountAccount(models.Model):
_inherit = 'account.account'
_inherit = "account.account"
centralized = fields.Boolean(
'Centralized',
"Centralized",
help="If flagged, no details will be displayed in "
"the General Ledger report (the webkit one only), "
"only centralized amounts per period.")
"the General Ledger report (the webkit one only), "
"only centralized amounts per period.",
)

60
account_financial_report/models/account_group.py

@ -5,49 +5,45 @@ from odoo import api, fields, models
class AccountGroup(models.Model):
_inherit = 'account.group'
_inherit = "account.group"
group_child_ids = fields.One2many(
comodel_name='account.group',
inverse_name='parent_id',
string='Child Groups')
level = fields.Integer(
string='Level',
compute='_compute_level',
store=True)
comodel_name="account.group", inverse_name="parent_id", string="Child Groups"
)
level = fields.Integer(string="Level", compute="_compute_level", store=True)
account_ids = fields.One2many(
comodel_name='account.account',
inverse_name='group_id',
string="Accounts")
comodel_name="account.account", inverse_name="group_id", string="Accounts"
)
compute_account_ids = fields.Many2many(
'account.account',
compute='_compute_group_accounts',
string="Compute accounts", store=True)
complete_name = fields.Char("Full Name",
compute='_compute_complete_name')
complete_code = fields.Char("Full Code",
compute='_compute_complete_code')
"account.account",
compute="_compute_group_accounts",
string="Compute accounts",
store=True,
)
complete_name = fields.Char("Full Name", compute="_compute_complete_name")
complete_code = fields.Char("Full Code", compute="_compute_complete_code")
@api.depends('name', 'parent_id.complete_name')
@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)
self.complete_name = "{}/{}".format(self.parent_id.complete_name, self.name)
else:
self.complete_name = self.name
@api.depends('code_prefix', 'parent_id.complete_code')
@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)
self.complete_code = "{}/{}".format(
self.parent_id.complete_code,
self.code_prefix,
)
else:
self.complete_code = self.code_prefix
@api.multi
@api.depends('parent_id', 'parent_id.level')
@api.depends("parent_id", "parent_id.level")
def _compute_level(self):
for group in self:
if not group.parent_id:
@ -56,13 +52,17 @@ class AccountGroup(models.Model):
group.level = group.parent_id.level + 1
@api.multi
@api.depends('code_prefix', 'account_ids', 'account_ids.code',
'group_child_ids', 'group_child_ids.account_ids.code')
@api.depends(
"code_prefix",
"account_ids",
"account_ids.code",
"group_child_ids",
"group_child_ids.account_ids.code",
)
def _compute_group_accounts(self):
account_obj = self.env['account.account']
account_obj = self.env["account.account"]
accounts = account_obj.search([])
for group in self:
prefix = group.code_prefix if group.code_prefix else group.name
gr_acc = accounts.filtered(
lambda a: a.code.startswith(prefix)).ids
gr_acc = accounts.filtered(lambda a: a.code.startswith(prefix)).ids
group.compute_account_ids = [(6, 0, gr_acc)]

15
account_financial_report/models/account_move_line.py

@ -4,7 +4,7 @@ from odoo import api, models
class AccountMoveLine(models.Model):
_inherit = 'account.move.line'
_inherit = "account.move.line"
@api.model_cr
def init(self):
@ -21,10 +21,13 @@ class AccountMoveLine(models.Model):
By adding the following index, performances are strongly increased.
:return:
"""
self._cr.execute('SELECT indexname FROM pg_indexes WHERE indexname = '
'%s',
('account_move_line_account_id_partner_id_index',))
self._cr.execute(
"SELECT indexname FROM pg_indexes WHERE indexname = " "%s",
("account_move_line_account_id_partner_id_index",),
)
if not self._cr.fetchone():
self._cr.execute("""
self._cr.execute(
"""
CREATE INDEX account_move_line_account_id_partner_id_index
ON account_move_line (account_id, partner_id)""")
ON account_move_line (account_id, partner_id)"""
)

449
account_financial_report/report/abstract_report_xlsx.py

@ -5,8 +5,8 @@ from odoo import models
class AbstractReportXslx(models.AbstractModel):
_name = 'report.account_financial_report.abstract_report_xlsx'
_inherit = 'report.report_xlsx.abstract'
_name = "report.account_financial_report.abstract_report_xlsx"
_inherit = "report.report_xlsx.abstract"
def __init__(self, pool, cr):
# main sheet which will contains report
@ -31,7 +31,7 @@ class AbstractReportXslx(models.AbstractModel):
self.format_percent_bold_italic = None
def get_workbook_options(self):
return {'constant_memory': True}
return {"constant_memory": True}
def generate_xlsx_report(self, workbook, data, objects):
report = objects
@ -71,58 +71,57 @@ class AbstractReportXslx(models.AbstractModel):
* format_amount
* format_percent_bold_italic
"""
self.format_bold = workbook.add_format({'bold': True})
self.format_right = workbook.add_format({'align': 'right'})
self.format_left = workbook.add_format({'align': 'left'})
self.format_bold = workbook.add_format({"bold": True})
self.format_right = workbook.add_format({"align": "right"})
self.format_left = workbook.add_format({"align": "left"})
self.format_right_bold_italic = workbook.add_format(
{'align': 'right', 'bold': True, 'italic': True}
{"align": "right", "bold": True, "italic": True}
)
self.format_header_left = workbook.add_format(
{'bold': True,
'border': True,
'bg_color': '#FFFFCC'})
{"bold": True, "border": True, "bg_color": "#FFFFCC"}
)
self.format_header_center = workbook.add_format(
{'bold': True,
'align': 'center',
'border': True,
'bg_color': '#FFFFCC'})
{"bold": True, "align": "center", "border": True, "bg_color": "#FFFFCC"}
)
self.format_header_right = workbook.add_format(
{'bold': True,
'align': 'right',
'border': True,
'bg_color': '#FFFFCC'})
{"bold": True, "align": "right", "border": True, "bg_color": "#FFFFCC"}
)
self.format_header_amount = workbook.add_format(
{'bold': True,
'border': True,
'bg_color': '#FFFFCC'})
currency_id = self.env['res.company']._get_user_currency()
{"bold": True, "border": True, "bg_color": "#FFFFCC"}
)
currency_id = self.env["res.company"]._get_user_currency()
self.format_header_amount.set_num_format(
'#,##0.'+'0'*currency_id.decimal_places)
"#,##0." + "0" * currency_id.decimal_places
)
self.format_amount = workbook.add_format()
self.format_amount.set_num_format(
'#,##0.'+'0'*currency_id.decimal_places)
self.format_amount_bold = workbook.add_format({'bold': True})
self.format_amount.set_num_format("#,##0." + "0" * currency_id.decimal_places)
self.format_amount_bold = workbook.add_format({"bold": True})
self.format_amount_bold.set_num_format(
'#,##0.' + '0' * currency_id.decimal_places)
"#,##0." + "0" * currency_id.decimal_places
)
self.format_percent_bold_italic = workbook.add_format(
{'bold': True, 'italic': True}
{"bold": True, "italic": True}
)
self.format_percent_bold_italic.set_num_format('#,##0.00%')
self.format_percent_bold_italic.set_num_format("#,##0.00%")
def _set_column_width(self):
"""Set width for all defined columns.
Columns are defined with `_get_report_columns` method.
"""
for position, column in self.columns.items():
self.sheet.set_column(position, position, column['width'])
self.sheet.set_column(position, position, column["width"])
def _write_report_title(self, title):
"""Write report title on current line using all defined columns width.
Columns are defined with `_get_report_columns` method.
"""
self.sheet.merge_range(
self.row_pos, 0, self.row_pos, len(self.columns) - 1,
title, self.format_bold
self.row_pos,
0,
self.row_pos,
len(self.columns) - 1,
title,
self.format_bold,
)
self.row_pos += 3
@ -133,8 +132,12 @@ class AbstractReportXslx(models.AbstractModel):
if footer:
self.row_pos += 1
self.sheet.merge_range(
self.row_pos, 0, self.row_pos, len(self.columns) - 1,
footer, self.format_left
self.row_pos,
0,
self.row_pos,
len(self.columns) - 1,
footer,
self.format_left,
)
self.row_pos += 1
@ -151,13 +154,20 @@ class AbstractReportXslx(models.AbstractModel):
col_value = col_name + col_count_filter_name + 1
for title, value in filters:
self.sheet.merge_range(
self.row_pos, col_name,
self.row_pos, col_name + col_count_filter_name - 1,
title, self.format_header_left)
self.row_pos,
col_name,
self.row_pos,
col_name + col_count_filter_name - 1,
title,
self.format_header_left,
)
self.sheet.merge_range(
self.row_pos, col_value,
self.row_pos, col_value + col_count_filter_value - 1,
value)
self.row_pos,
col_value,
self.row_pos,
col_value + col_count_filter_value - 1,
value,
)
self.row_pos += 1
self.row_pos += 2
@ -166,8 +176,12 @@ class AbstractReportXslx(models.AbstractModel):
Columns are defined with `_get_report_columns` method.
"""
self.sheet.merge_range(
self.row_pos, 0, self.row_pos, len(self.columns) - 1,
title, self.format_bold
self.row_pos,
0,
self.row_pos,
len(self.columns) - 1,
title,
self.format_bold,
)
self.row_pos += 1
@ -176,8 +190,9 @@ class AbstractReportXslx(models.AbstractModel):
Columns are defined with `_get_report_columns` method.
"""
for col_pos, column in self.columns.items():
self.sheet.write(self.row_pos, col_pos, column['header'],
self.format_header_center)
self.sheet.write(
self.row_pos, col_pos, column["header"], self.format_header_center
)
self.row_pos += 1
def write_line(self, line_object):
@ -185,28 +200,34 @@ class AbstractReportXslx(models.AbstractModel):
Columns are defined with `_get_report_columns` method.
"""
for col_pos, column in self.columns.items():
value = getattr(line_object, column['field'])
cell_type = column.get('type', 'string')
if cell_type == 'many2one':
value = getattr(line_object, column["field"])
cell_type = column.get("type", "string")
if cell_type == "many2one":
self.sheet.write_string(
self.row_pos, col_pos, value.name or '', self.format_right)
elif cell_type == 'string':
if hasattr(line_object, 'account_group_id') and \
line_object.account_group_id:
self.sheet.write_string(self.row_pos, col_pos, value or '',
self.format_bold)
self.row_pos, col_pos, value.name or "", self.format_right
)
elif cell_type == "string":
if (
hasattr(line_object, "account_group_id")
and line_object.account_group_id
):
self.sheet.write_string(
self.row_pos, col_pos, value or "", self.format_bold
)
else:
self.sheet.write_string(self.row_pos, col_pos, value or '')
elif cell_type == 'amount':
if hasattr(line_object, 'account_group_id') and \
line_object.account_group_id:
self.sheet.write_string(self.row_pos, col_pos, value or "")
elif cell_type == "amount":
if (
hasattr(line_object, "account_group_id")
and line_object.account_group_id
):
cell_format = self.format_amount_bold
else:
cell_format = self.format_amount
self.sheet.write_number(
self.row_pos, col_pos, float(value), cell_format
)
elif cell_type == 'amount_currency':
elif cell_type == "amount_currency":
if line_object.currency_id:
format_amt = self._get_currency_amt_format(line_object)
self.sheet.write_number(
@ -218,40 +239,45 @@ class AbstractReportXslx(models.AbstractModel):
"""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']):
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)
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):
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']:
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)
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':
elif cell_type == "currency_name":
self.sheet.write_string(
self.row_pos, col_pos, value or '', self.format_right)
self.row_pos, col_pos, value or "", self.format_right
)
self.row_pos += 1
def write_initial_balance(self, my_object, label):
@ -262,32 +288,28 @@ class AbstractReportXslx(models.AbstractModel):
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 = getattr(my_object, column['field_initial_balance'])
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':
if column.get("field_initial_balance"):
value = getattr(my_object, column["field_initial_balance"])
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':
elif cell_type == "amount_currency":
if my_object.currency_id:
format_amt = self._get_currency_amt_format(
my_object)
format_amt = self._get_currency_amt_format(my_object)
self.sheet.write_number(
self.row_pos, col_pos,
float(value), format_amt
self.row_pos, col_pos, float(value), format_amt
)
elif column.get('field_currency_balance'):
value = getattr(my_object, column['field_currency_balance'])
cell_type = column.get('type', 'string')
if cell_type == 'many2one':
elif column.get("field_currency_balance"):
value = getattr(my_object, column["field_currency_balance"])
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, col_pos, value.name or "", self.format_right
)
self.row_pos += 1
@ -299,32 +321,28 @@ class AbstractReportXslx(models.AbstractModel):
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':
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)
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
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']:
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, col_pos, value.name or "", self.format_right
)
self.row_pos += 1
@ -334,44 +352,46 @@ class AbstractReportXslx(models.AbstractModel):
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)
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.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)
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 = getattr(my_object, column['field_final_balance'])
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':
if column.get("field_final_balance"):
value = getattr(my_object, column["field_final_balance"])
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
self.row_pos, col_pos, float(value), self.format_header_amount
)
elif cell_type == 'amount_currency':
elif cell_type == "amount_currency":
if my_object.currency_id:
format_amt = self._get_currency_amt_header_format(
my_object)
format_amt = self._get_currency_amt_header_format(my_object)
self.sheet.write_number(
self.row_pos, col_pos, float(value),
format_amt
self.row_pos, col_pos, float(value), format_amt
)
elif column.get('field_currency_balance'):
value = getattr(my_object, column['field_currency_balance'])
cell_type = column.get('type', 'string')
if cell_type == 'many2one':
elif column.get("field_currency_balance"):
value = getattr(my_object, column["field_currency_balance"])
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_header_right
self.row_pos,
col_pos,
value.name or "",
self.format_header_right,
)
self.row_pos += 1
@ -381,129 +401,120 @@ class AbstractReportXslx(models.AbstractModel):
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)
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.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)
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':
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
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)
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
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']:
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, col_pos, value or "", self.format_header_right
)
self.row_pos += 1
def _get_currency_amt_format(self, line_object):
""" Return amount format specific for each currency. """
if hasattr(line_object, 'account_group_id') and \
line_object.account_group_id:
format_amt = getattr(self, 'format_amount_bold')
field_prefix = 'format_amount_bold'
if hasattr(line_object, "account_group_id") and line_object.account_group_id:
format_amt = getattr(self, "format_amount_bold")
field_prefix = "format_amount_bold"
else:
format_amt = getattr(self, 'format_amount')
field_prefix = 'format_amount'
format_amt = getattr(self, "format_amount")
field_prefix = "format_amount"
if line_object.currency_id:
field_name = \
'%s_%s' % (field_prefix, line_object.currency_id.name)
field_name = "{}_{}".format(field_prefix, line_object.currency_id.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' * line_object.currency_id.decimal_places)
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 _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'
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)
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 = "{}_{}".format(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)
setattr(self, "field_name", format_amt)
format_amount = "#,##0." + ("0" * currency.decimal_places)
format_amt.set_num_format(format_amount)
return format_amt
def _get_currency_amt_header_format(self, line_object):
""" Return amount header format for each currency. """
format_amt = getattr(self, 'format_header_amount')
format_amt = getattr(self, "format_header_amount")
if line_object.currency_id:
field_name = \
'format_header_amount_%s' % line_object.currency_id.name
field_name = "format_header_amount_%s" % line_object.currency_id.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)
{"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 _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']
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)
{"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
@ -515,8 +526,10 @@ class AbstractReportXslx(models.AbstractModel):
def _get_report_complete_name(self, report, prefix, data=None):
if report.company_id:
suffix = ' - %s - %s' % (
report.company_id.name, report.company_id.currency_id.name)
suffix = " - {} - {}".format(
report.company_id.name,
report.company_id.currency_id.name,
)
return prefix + suffix
return prefix

538
account_financial_report/report/aged_partner_balance.py

@ -2,175 +2,217 @@
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, api
from odoo.tools import float_is_zero
from datetime import date, datetime, timedelta
import pandas as pd
from odoo import api, models
from odoo.tools import float_is_zero
class AgedPartnerBalanceReport(models.AbstractModel):
_name = 'report.account_financial_report.aged_partner_balance'
_name = "report.account_financial_report.aged_partner_balance"
@api.model
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
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
@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'] = []
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 = self.env["account.journal"].browse(journals_ids)
journals_data = {}
for journal in journals:
journals_data.update({journal.id: {'id': journal.id,
'code': journal.code}})
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 = 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}})
accounts_data.update(
{
account.id: {
"id": account.id,
"code": account.code,
"name": account.name,
}
}
)
return accounts_data
@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)]
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)]
domain += [("partner_id", "in", partner_ids)]
if only_posted_moves:
domain += [('move_id.state', '=', 'posted')]
domain += [("move_id.state", "=", "posted")]
return domain
@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
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
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
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
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
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
ag_pb_data[acc_id]["120_days"] += residual
ag_pb_data[acc_id][prt_id]["120_days"] += residual
else:
ag_pb_data[acc_id]['older'] += residual
ag_pb_data[acc_id][prt_id]['older'] += residual
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
)
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]
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']
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,
})
credit_amount[credit_move_id] += account_partial_reconcile_data["amount"]
account_partial_reconcile_data.update(
{"debit_move_id": debit_move_id, "credit_move_id": credit_move_id,}
)
return accounts_partial_reconcile, debit_amount, credit_amount
@api.model
def _get_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)]
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)]
domain += [("partner_id", "in", partner_ids)]
if only_posted_moves:
domain += [('move_id.state', '=', 'posted')]
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):
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)
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(
"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
)
move_lines = move_lines + new_move_lines
for move_line in move_lines:
ml_id = move_line['id']
ml_id = move_line["id"]
if ml_id in debit_ids:
move_line['amount_residual'] += debit_amount[ml_id]
move_line["amount_residual"] += debit_amount[ml_id]
if ml_id in credit_ids:
move_line['amount_residual'] -= credit_amount[ml_id]
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)
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(
"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
)
ml_ids = set(pd.DataFrame(move_lines).id.to_list())
@ -179,196 +221,240 @@ class AgedPartnerBalanceReport(models.AbstractModel):
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)
(
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
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):
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]
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_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)
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)
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)
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
@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']
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
ml["current"] += amount
elif today <= due_date + timedelta(days=30):
ml['30_days'] += amount
ml["30_days"] += amount
elif today <= due_date + timedelta(days=60):
ml['60_days'] += amount
ml["60_days"] += amount
elif today <= due_date + timedelta(days=90):
ml['90_days'] += amount
ml["90_days"] += amount
elif today <= due_date + timedelta(days=120):
ml['120_days'] += amount
ml["120_days"] += amount
else:
ml['older'] += amount
ml["older"] += amount
def _create_account_list(
self, ag_pb_data, accounts_data, partners_data, journals_data,
show_move_line_details, date_at_oject):
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': [],
})
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'],
"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'],
})
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)
partner.update({"move_lines": move_lines})
account["partners"].append(partner)
aged_partner_data.append(account)
return aged_partner_data
@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)),
})
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,
})
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
@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)
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)
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,
"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,
}

338
account_financial_report/report/aged_partner_balance_xlsx.py

@ -1,4 +1,3 @@
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
@ -7,129 +6,159 @@ from odoo import _, models
class AgedPartnerBalanceXslx(models.AbstractModel):
_name = 'report.a_f_r.report_aged_partner_balance_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
_name = "report.a_f_r.report_aged_partner_balance_xlsx"
_inherit = "report.account_financial_report.abstract_report_xlsx"
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('Aged Partner Balance')
company_id = data.get("company_id", False)
report_name = _("Aged Partner Balance")
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
company = self.env["res.company"].browse(company_id)
suffix = " - {} - {}".format(company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
if not report.show_move_line_details:
return {
0: {'header': _('Partner'), 'field': 'name', 'width': 70},
1: {'header': _('Residual'),
'field': 'residual',
'field_footer_total': 'residual',
'type': 'amount',
'width': 14},
2: {'header': _('Current'),
'field': 'current',
'field_footer_total': 'current',
'field_footer_percent': 'percent_current',
'type': 'amount',
'width': 14},
3: {'header': _(u'Age ≤ 30 d.'),
'field': '30_days',
'field_footer_total': '30_days',
'field_footer_percent': 'percent_30_days',
'type': 'amount',
'width': 14},
4: {'header': _(u'Age ≤ 60 d.'),
'field': '60_days',
'field_footer_total': '60_days',
'field_footer_percent': 'percent_60_days',
'type': 'amount',
'width': 14},
5: {'header': _(u'Age ≤ 90 d.'),
'field': '90_days',
'field_footer_total': '90_days',
'field_footer_percent': 'percent_90_days',
'type': 'amount',
'width': 14},
6: {'header': _(u'Age ≤ 120 d.'),
'field': '120_days',
'field_footer_total': '120_days',
'field_footer_percent': 'percent_120_days',
'type': 'amount',
'width': 14},
7: {'header': _('Older'),
'field': 'older',
'field_footer_total': 'older',
'field_footer_percent': 'percent_older',
'type': 'amount',
'width': 14},
0: {"header": _("Partner"), "field": "name", "width": 70},
1: {
"header": _("Residual"),
"field": "residual",
"field_footer_total": "residual",
"type": "amount",
"width": 14,
},
2: {
"header": _("Current"),
"field": "current",
"field_footer_total": "current",
"field_footer_percent": "percent_current",
"type": "amount",
"width": 14,
},
3: {
"header": _(u"Age ≤ 30 d."),
"field": "30_days",
"field_footer_total": "30_days",
"field_footer_percent": "percent_30_days",
"type": "amount",
"width": 14,
},
4: {
"header": _(u"Age ≤ 60 d."),
"field": "60_days",
"field_footer_total": "60_days",
"field_footer_percent": "percent_60_days",
"type": "amount",
"width": 14,
},
5: {
"header": _(u"Age ≤ 90 d."),
"field": "90_days",
"field_footer_total": "90_days",
"field_footer_percent": "percent_90_days",
"type": "amount",
"width": 14,
},
6: {
"header": _(u"Age ≤ 120 d."),
"field": "120_days",
"field_footer_total": "120_days",
"field_footer_percent": "percent_120_days",
"type": "amount",
"width": 14,
},
7: {
"header": _("Older"),
"field": "older",
"field_footer_total": "older",
"field_footer_percent": "percent_older",
"type": "amount",
"width": 14,
},
}
return {
0: {'header': _('Date'), 'field': 'date', 'width': 11},
1: {'header': _('Entry'), 'field': 'entry', 'width': 18},
2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
3: {'header': _('Account'), 'field': 'account', 'width': 9},
4: {'header': _('Partner'), 'field': 'partner', 'width': 25},
5: {'header': _('Ref - Label'), 'field': 'ref', 'width': 40},
6: {'header': _('Due date'), 'field': 'due_date', 'width': 11},
7: {'header': _('Residual'),
'field': 'residual',
'field_footer_total': 'residual',
'field_final_balance': 'residual',
'type': 'amount',
'width': 14},
8: {'header': _('Current'),
'field': 'current',
'field_footer_total': 'current',
'field_footer_percent': 'percent_current',
'field_final_balance': 'current',
'type': 'amount',
'width': 14},
9: {'header': _(u'Age ≤ 30 d.'),
'field': '30_days',
'field_footer_total': '30_days',
'field_footer_percent': 'percent_30_days',
'field_final_balance': '30_days',
'type': 'amount',
'width': 14},
10: {'header': _(u'Age ≤ 60 d.'),
'field': '60_days',
'field_footer_total': '60_days',
'field_footer_percent': 'percent_60_days',
'field_final_balance': '60_days',
'type': 'amount',
'width': 14},
11: {'header': _(u'Age ≤ 90 d.'),
'field': '90_days',
'field_footer_total': '90_days',
'field_footer_percent': 'percent_90_days',
'field_final_balance': '90_days',
'type': 'amount',
'width': 14},
12: {'header': _(u'Age ≤ 120 d.'),
'field': '120_days',
'field_footer_total': '120_days',
'field_footer_percent': 'percent_120_days',
'field_final_balance': '120_days',
'type': 'amount',
'width': 14},
13: {'header': _('Older'),
'field': 'older',
'field_footer_total': 'older',
'field_footer_percent': 'percent_older',
'field_final_balance': 'older',
'type': 'amount',
'width': 14},
0: {"header": _("Date"), "field": "date", "width": 11},
1: {"header": _("Entry"), "field": "entry", "width": 18},
2: {"header": _("Journal"), "field": "journal", "width": 8},
3: {"header": _("Account"), "field": "account", "width": 9},
4: {"header": _("Partner"), "field": "partner", "width": 25},
5: {"header": _("Ref - Label"), "field": "ref", "width": 40},
6: {"header": _("Due date"), "field": "due_date", "width": 11},
7: {
"header": _("Residual"),
"field": "residual",
"field_footer_total": "residual",
"field_final_balance": "residual",
"type": "amount",
"width": 14,
},
8: {
"header": _("Current"),
"field": "current",
"field_footer_total": "current",
"field_footer_percent": "percent_current",
"field_final_balance": "current",
"type": "amount",
"width": 14,
},
9: {
"header": _(u"Age ≤ 30 d."),
"field": "30_days",
"field_footer_total": "30_days",
"field_footer_percent": "percent_30_days",
"field_final_balance": "30_days",
"type": "amount",
"width": 14,
},
10: {
"header": _(u"Age ≤ 60 d."),
"field": "60_days",
"field_footer_total": "60_days",
"field_footer_percent": "percent_60_days",
"field_final_balance": "60_days",
"type": "amount",
"width": 14,
},
11: {
"header": _(u"Age ≤ 90 d."),
"field": "90_days",
"field_footer_total": "90_days",
"field_footer_percent": "percent_90_days",
"field_final_balance": "90_days",
"type": "amount",
"width": 14,
},
12: {
"header": _(u"Age ≤ 120 d."),
"field": "120_days",
"field_footer_total": "120_days",
"field_footer_percent": "percent_120_days",
"field_final_balance": "120_days",
"type": "amount",
"width": 14,
},
13: {
"header": _("Older"),
"field": "older",
"field_footer_total": "older",
"field_footer_percent": "percent_older",
"field_final_balance": "older",
"type": "amount",
"width": 14,
},
}
def _get_report_filters(self, report):
return [
[_('Date at filter'), report.date_at.strftime("%d/%m/%Y")],
[_('Target moves filter'),
_('All posted entries') if report.target_move == 'posted' else _(
'All entries')],
[_("Date at filter"), report.date_at.strftime("%d/%m/%Y")],
[
_("Target moves filter"),
_("All posted entries")
if report.target_move == "posted"
else _("All entries"),
],
]
def _get_col_count_filter_name(self):
@ -149,32 +178,42 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.aged_partner_balance'
"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']
show_move_line_details = res_data["show_move_lines_details"]
aged_partner_balance = res_data["aged_partner_balance"]
if not show_move_line_details:
# For each account
for account in aged_partner_balance:
# Write account title
self.write_array_title(account['code'] + ' - ' + account[
'name'])
self.write_array_title(account["code"] + " - " + account["name"])
# Display array header for partners lines
self.write_array_header()
# Display partner lines
for partner in account['partners']:
for partner in account["partners"]:
self.write_line_from_dict(partner)
# Display account lines
self.write_account_footer_from_dict(
report, account, ('Total'), 'field_footer_total',
self.format_header_right, self.format_header_amount, False)
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',
report,
account,
("Percents"),
"field_footer_percent",
self.format_right_bold_italic,
self.format_percent_bold_italic, True)
self.format_percent_bold_italic,
True,
)
# 2 lines break
self.row_pos += 2
@ -182,19 +221,18 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
# For each account
for account in aged_partner_balance:
# Write account title
self.write_array_title(account['code'] + ' - ' + account[
'name'])
self.write_array_title(account["code"] + " - " + account["name"])
# For each partner
for partner in account['partners']:
for partner in account["partners"]:
# Write partner title
self.write_array_title(partner['name'])
self.write_array_title(partner["name"])
# Display array header for move lines
self.write_array_header()
# Display account move lines
for line in partner['move_lines']:
for line in partner["move_lines"]:
self.write_line_from_dict(line)
# Display ending balance line for partner
@ -205,13 +243,24 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
# Display account lines
self.write_account_footer_from_dict(
report, account, ('Total'), 'field_footer_total',
self.format_header_right, self.format_header_amount, False)
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',
report,
account,
("Percents"),
"field_footer_percent",
self.format_right_bold_italic,
self.format_percent_bold_italic, True)
self.format_percent_bold_italic,
True,
)
# 2 lines break
self.row_pos += 2
@ -222,14 +271,21 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
for Aged Partner Balance
"""
name = None
label = _('Partner cumul aged balance')
label = _("Partner cumul aged balance")
super(AgedPartnerBalanceXslx, self).write_ending_balance_from_dict(
my_object, name, label
)
def write_account_footer_from_dict(
self, report, account, label, field_name, string_format,
amount_format, amount_is_percent):
self,
report,
account,
label,
field_name,
string_format,
amount_format,
amount_is_percent,
):
"""
Specific function to write account footer for Aged Partner Balance
"""
@ -240,19 +296,19 @@ class AgedPartnerBalanceXslx(models.AbstractModel):
value = label
else:
value = account.get(column[field_name], False)
cell_type = column.get('type', 'string')
if cell_type == 'string' or col_pos == col_pos_footer_label:
self.sheet.write_string(self.row_pos, col_pos, value or '',
string_format)
elif cell_type == 'amount':
cell_type = column.get("type", "string")
if cell_type == "string" or col_pos == col_pos_footer_label:
self.sheet.write_string(
self.row_pos, col_pos, value or "", string_format
)
elif cell_type == "amount":
number = float(value)
if amount_is_percent:
number /= 100
self.sheet.write_number(self.row_pos, col_pos,
number,
amount_format)
self.sheet.write_number(
self.row_pos, col_pos, number, amount_format
)
else:
self.sheet.write_string(self.row_pos, col_pos, '',
string_format)
self.sheet.write_string(self.row_pos, col_pos, "", string_format)
self.row_pos += 1

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

353
account_financial_report/report/general_ledger_xlsx.py

@ -1,4 +1,3 @@
# Author: Damien Crier
# Author: Julien Coux
# Copyright 2016 Camptocamp SA
@ -8,70 +7,72 @@ from odoo import _, models
class GeneralLedgerXslx(models.AbstractModel):
_name = 'report.a_f_r.report_general_ledger_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
_name = "report.a_f_r.report_general_ledger_xlsx"
_inherit = "report.account_financial_report.abstract_report_xlsx"
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('General Ledger')
company_id = data.get("company_id", False)
report_name = _("General Ledger")
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
company = self.env["res.company"].browse(company_id)
suffix = " - {} - {}".format(company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
res = {
0: {'header': _('Date'), 'field': 'date', 'width': 11},
1: {'header': _('Entry'), 'field': 'entry', 'width': 18},
2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
3: {'header': _('Account'), 'field': 'account', 'width': 9},
4: {'header': _('Taxes'),
'field': 'taxes_description',
'width': 15},
5: {'header': _('Partner'), 'field': 'partner_name', 'width': 25},
6: {'header': _('Ref - Label'), 'field': 'ref', 'width': 40},
7: {'header': _('Cost center'),
'field': 'cost_center',
'width': 15},
8: {'header': _('Tags'),
'field': 'tags',
'width': 10},
9: {'header': _('Rec.'), 'field': 'rec_name', 'width': 5},
10: {'header': _('Debit'),
'field': 'debit',
'field_initial_balance': 'initial_debit',
'field_final_balance': 'final_debit',
'type': 'amount',
'width': 14},
11: {'header': _('Credit'),
'field': 'credit',
'field_initial_balance': 'initial_credit',
'field_final_balance': 'final_credit',
'type': 'amount',
'width': 14},
12: {'header': _('Cumul. Bal.'),
'field': 'balance',
'field_initial_balance': 'initial_balance',
'field_final_balance': 'final_balance',
'type': 'amount',
'width': 14},
0: {"header": _("Date"), "field": "date", "width": 11},
1: {"header": _("Entry"), "field": "entry", "width": 18},
2: {"header": _("Journal"), "field": "journal", "width": 8},
3: {"header": _("Account"), "field": "account", "width": 9},
4: {"header": _("Taxes"), "field": "taxes_description", "width": 15},
5: {"header": _("Partner"), "field": "partner_name", "width": 25},
6: {"header": _("Ref - Label"), "field": "ref", "width": 40},
7: {"header": _("Cost center"), "field": "cost_center", "width": 15},
8: {"header": _("Tags"), "field": "tags", "width": 10},
9: {"header": _("Rec."), "field": "rec_name", "width": 5},
10: {
"header": _("Debit"),
"field": "debit",
"field_initial_balance": "initial_debit",
"field_final_balance": "final_debit",
"type": "amount",
"width": 14,
},
11: {
"header": _("Credit"),
"field": "credit",
"field_initial_balance": "initial_credit",
"field_final_balance": "final_credit",
"type": "amount",
"width": 14,
},
12: {
"header": _("Cumul. Bal."),
"field": "balance",
"field_initial_balance": "initial_balance",
"field_final_balance": "final_balance",
"type": "amount",
"width": 14,
},
}
if report.foreign_currency:
foreign_currency = {
13: {'header': _('Cur.'),
'field': 'currency_name',
'field_currency_balance': 'currency_name',
'type': 'currency_name', 'width': 7},
14: {'header': _('Amount cur.'),
'field': 'bal_curr',
'field_initial_balance':
'initial_bal_curr',
'field_final_balance':
'final_bal_curr',
'type': 'amount_currency',
'width': 14},
13: {
"header": _("Cur."),
"field": "currency_name",
"field_currency_balance": "currency_name",
"type": "currency_name",
"width": 7,
},
14: {
"header": _("Amount cur."),
"field": "bal_curr",
"field_initial_balance": "initial_bal_curr",
"field_final_balance": "final_bal_curr",
"type": "amount_currency",
"width": 14,
},
}
res = {**res, **foreign_currency}
return res
@ -79,29 +80,27 @@ class GeneralLedgerXslx(models.AbstractModel):
def _get_report_filters(self, report):
return [
[
_('Date range filter'),
_('From: %s To: %s') % (report.date_from, report.date_to),
],
[
_('Target moves filter'),
_('All posted entries') if report.target_move == 'all' else _(
'All entries'),
_("Date range filter"),
_("From: %s To: %s") % (report.date_from, report.date_to),
],
[
_('Account balance at 0 filter'),
_('Hide') if report.hide_account_at_0 else _('Show'),
_("Target moves filter"),
_("All posted entries")
if report.target_move == "all"
else _("All entries"),
],
[
_('Centralize filter'),
_('Yes') if report.centralize else _('No'),
_("Account balance at 0 filter"),
_("Hide") if report.hide_account_at_0 else _("Show"),
],
[_("Centralize filter"), _("Yes") if report.centralize else _("No"),],
[
_('Show analytic tags'),
_('Yes') if report.show_analytic_tags else _('No'),
_("Show analytic tags"),
_("Yes") if report.show_analytic_tags else _("No"),
],
[
_('Show foreign currency'),
_('Yes') if report.foreign_currency else _('No')
_("Show foreign currency"),
_("Yes") if report.foreign_currency else _("No"),
],
]
@ -122,120 +121,136 @@ class GeneralLedgerXslx(models.AbstractModel):
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.general_ledger'
"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']
general_ledger = res_data["general_ledger"]
accounts_data = res_data["accounts_data"]
partners_data = res_data["partners_data"]
journals_data = res_data["journals_data"]
taxes_data = res_data["taxes_data"]
tags_data = res_data["tags_data"]
filter_partner_ids = res_data["filter_partner_ids"]
foreign_currency = res_data["foreign_currency"]
# For each account
for account in general_ledger:
# Write account title
self.write_array_title(account['code'] + ' - ' + accounts_data[
account['id']]['name'])
self.write_array_title(
account["code"] + " - " + accounts_data[account["id"]]["name"]
)
if not account['partners']:
if not account["partners"]:
# Display array header for move lines
self.write_array_header()
# Display initial balance line for account
account.update({
'initial_debit': account['init_bal']['debit'],
'initial_credit': account['init_bal']['credit'],
'initial_balance': account['init_bal']['balance'],
})
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'],
})
account.update(
{"initial_bal_curr": account["init_bal"]["bal_curr"],}
)
self.write_initial_balance_from_dict(account)
# Display account move lines
for line in account['move_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':
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,
})
for tax_id in line["tax_ids"]:
taxes_description += (
str(taxes_data[tax_id]["amount"])
+ " "
+ taxes_data[tax_id]["string"]
+ " "
)
for tag_id in line["tag_ids"]:
tags += tags_data[tag_id]["name"] + " "
line.update(
{"taxes_description": taxes_description, "tags": tags,}
)
self.write_line_from_dict(line)
else:
# For each partner
for partner in account['list_partner']:
for partner in account["list_partner"]:
# Write partner title
self.write_array_title(partners_data[partner['id']]['name'])
self.write_array_title(partners_data[partner["id"]]["name"])
# Display array header for move lines
self.write_array_header()
# Display initial balance line for partner
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'],
})
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'],
})
partner.update(
{"initial_bal_culrr": partner["init_bal"]["bal_curr"],}
)
self.write_initial_balance_from_dict(partner)
# Display account move lines
for line in partner['move_lines']:
line.update({
'account': account['code'],
'journal': journals_data[line['journal_id']]['code']
})
if line['ref'] != 'Centralized entries':
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,
})
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
partner.update({
'final_debit': partner['fin_bal']['debit'],
'final_credit': partner['fin_bal']['credit'],
'final_balance': partner['fin_bal']['balance'],
})
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'],
})
partner.update(
{"final_bal_curr": partner["fin_bal"]["bal_curr"],}
)
self.write_ending_balance_from_dict(partner)
# Line break
@ -243,15 +258,17 @@ class GeneralLedgerXslx(models.AbstractModel):
# Display ending balance line for 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'],
})
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'],
})
account.update(
{"final_bal_curr": account["fin_bal"]["bal_curr"],}
)
self.write_ending_balance_from_dict(account)
# 2 lines break
@ -259,22 +276,20 @@ class GeneralLedgerXslx(models.AbstractModel):
def write_initial_balance_from_dict(self, my_object):
"""Specific function to write initial balance for General Ledger"""
if 'partner' in my_object['type']:
label = _('Partner Initial balance')
elif 'account' in my_object['type']:
label = _('Initial balance')
super(GeneralLedgerXslx, self).write_initial_balance_from_dict(
my_object, label
)
if "partner" in my_object["type"]:
label = _("Partner Initial balance")
elif "account" in my_object["type"]:
label = _("Initial balance")
super(GeneralLedgerXslx, self).write_initial_balance_from_dict(my_object, label)
def write_ending_balance_from_dict(self, my_object):
"""Specific function to write ending balance for General Ledger"""
if 'partner' in my_object['type']:
name = my_object['name']
label = _('Partner ending balance')
elif 'account' in my_object['type']:
name = my_object['code'] + ' - ' + my_object['name']
label = _('Ending balance')
if "partner" in my_object["type"]:
name = my_object["name"]
label = _("Partner ending balance")
elif "account" in my_object["type"]:
name = my_object["code"] + " - " + my_object["name"]
label = _("Ending balance")
super(GeneralLedgerXslx, self).write_ending_balance_from_dict(
my_object, name, label
)

362
account_financial_report/report/journal_ledger.py

@ -1,73 +1,75 @@
# Copyright 2019-20 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo import api, models
import operator
import itertools
import operator
from odoo import api, models
class JournalLedgerReport(models.AbstractModel):
_name = 'report.account_financial_report.journal_ledger'
_name = "report.account_financial_report.journal_ledger"
def _get_journal_ledger_data(self, journal):
return {
'id': journal.id,
'name': journal.name,
'currency_id': journal.currency_id.id,
'currency_name': journal.currency_id and
journal.currency_id.name or
journal.company_id.currency_id.name,
'debit': 0.0,
'credit': 0.0,
"id": journal.id,
"name": journal.name,
"currency_id": journal.currency_id.id,
"currency_name": journal.currency_id
and journal.currency_id.name
or journal.company_id.currency_id.name,
"debit": 0.0,
"credit": 0.0,
}
def _get_journal_ledgers_domain(self, wizard, journal_ids, company):
domain = []
if company:
domain += [('company_id', '=', company.id)]
domain += [("company_id", "=", company.id)]
if journal_ids:
domain += [('id', 'in', journal_ids)]
domain += [("id", "in", journal_ids)]
return domain
def _get_journal_ledgers(self, wizard, journal_ids, company):
journals = self.env['account.journal'].search(
journals = self.env["account.journal"].search(
self._get_journal_ledgers_domain(wizard, journal_ids, company),
order='name asc')
order="name asc",
)
journal_ledgers_data = []
for journal in journals:
journal_ledgers_data.append(
self._get_journal_ledger_data(journal))
journal_ledgers_data.append(self._get_journal_ledger_data(journal))
return journal_ledgers_data
def _get_moves_domain(self, wizard, journal_ids):
domain = [
('journal_id', 'in', journal_ids),
('date', '>=', wizard.date_from),
('date', '<=', wizard.date_to),
("journal_id", "in", journal_ids),
("date", ">=", wizard.date_from),
("date", "<=", wizard.date_to),
]
if wizard.move_target != 'all':
domain += [('state', '=', wizard.move_target)]
if wizard.move_target != "all":
domain += [("state", "=", wizard.move_target)]
return domain
def _get_moves_order(self, wizard, journal_ids):
search_order = ''
if wizard.sort_option == 'move_name':
search_order = 'name asc'
elif wizard.sort_option == 'date':
search_order = 'date asc, name asc'
search_order = ""
if wizard.sort_option == "move_name":
search_order = "name asc"
elif wizard.sort_option == "date":
search_order = "date asc, name asc"
return search_order
def _get_moves_data(self, move):
return {
'move_id': move.id,
'journal_id': move.journal_id.id,
'entry': move.name,
"move_id": move.id,
"journal_id": move.journal_id.id,
"entry": move.name,
}
def _get_moves(self, wizard, journal_ids):
moves = self.env['account.move'].search(
moves = self.env["account.move"].search(
self._get_moves_domain(wizard, journal_ids),
order=self._get_moves_order(wizard, journal_ids))
order=self._get_moves_order(wizard, journal_ids),
)
Moves = []
move_data = {}
for move in moves:
@ -78,44 +80,45 @@ class JournalLedgerReport(models.AbstractModel):
def _get_move_lines_domain(self, move_ids, wizard, journal_ids):
return [
('move_id', 'in', move_ids),
("move_id", "in", move_ids),
]
def _get_move_lines_order(self, move_ids, wizard, journal_ids):
return ''
return ""
def _get_move_lines_data(self, ml, wizard, ml_taxes):
base_debit = base_credit = tax_debit = tax_credit = \
base_balance = tax_balance = 0.0
if ml.tax_exigible:
base_debit = ml_taxes and ml.debit or 0.0
base_credit = ml_taxes and ml.credit or 0.0
base_balance = ml_taxes and ml.balance or 0.0
tax_debit = ml.tax_line_id and ml.debit or 0.0
tax_credit = ml.tax_line_id and ml.credit or 0.0
tax_balance = ml.tax_line_id and ml.balance or 0.0
return {
'move_line_id': ml.id,
'move_id': ml.move_id.id,
'date': ml.date,
'journal_id': ml.journal_id.id,
'account_id': ml.account_id.id,
'partner_id': ml.partner_id.id,
'label': ml.name,
'debit': ml.debit,
'credit': ml.credit,
'company_currency_id': ml.company_currency_id.id,
'amount_currency': ml.amount_currency,
'currency_id': ml.currency_id.id,
'tax_line_id': ml.tax_line_id.id,
'tax_ids': list(ml_taxes.keys()),
'base_debit': base_debit,
'base_credit': base_credit,
'tax_debit': tax_debit,
'tax_credit': tax_credit,
'base_balance': base_balance,
'tax_balance': tax_balance,
}
base_debit = (
base_credit
) = tax_debit = tax_credit = base_balance = tax_balance = 0.0
if ml.tax_exigible:
base_debit = ml_taxes and ml.debit or 0.0
base_credit = ml_taxes and ml.credit or 0.0
base_balance = ml_taxes and ml.balance or 0.0
tax_debit = ml.tax_line_id and ml.debit or 0.0
tax_credit = ml.tax_line_id and ml.credit or 0.0
tax_balance = ml.tax_line_id and ml.balance or 0.0
return {
"move_line_id": ml.id,
"move_id": ml.move_id.id,
"date": ml.date,
"journal_id": ml.journal_id.id,
"account_id": ml.account_id.id,
"partner_id": ml.partner_id.id,
"label": ml.name,
"debit": ml.debit,
"credit": ml.credit,
"company_currency_id": ml.company_currency_id.id,
"amount_currency": ml.amount_currency,
"currency_id": ml.currency_id.id,
"tax_line_id": ml.tax_line_id.id,
"tax_ids": list(ml_taxes.keys()),
"base_debit": base_debit,
"base_credit": base_credit,
"tax_debit": tax_debit,
"tax_credit": tax_credit,
"base_balance": base_balance,
"tax_balance": tax_balance,
}
def _get_account_data(self, accounts):
data = {}
@ -125,9 +128,9 @@ class JournalLedgerReport(models.AbstractModel):
def _get_account_id_data(self, account):
return {
'name': account.name,
'code': account.code,
'internal_type': account.internal_type,
"name": account.name,
"code": account.code,
"internal_type": account.internal_type,
}
def _get_partner_data(self, partners):
@ -138,7 +141,7 @@ class JournalLedgerReport(models.AbstractModel):
def _get_partner_id_data(self, partner):
return {
'name': partner.name,
"name": partner.name,
}
def _get_currency_data(self, currencies):
@ -149,7 +152,7 @@ class JournalLedgerReport(models.AbstractModel):
def _get_currency_id_data(self, currency):
return {
'name': currency.name,
"name": currency.name,
}
def _get_tax_line_data(self, taxes):
@ -160,8 +163,8 @@ class JournalLedgerReport(models.AbstractModel):
def _get_tax_line_id_data(self, tax):
return {
'name': tax.name,
'description': tax.description,
"name": tax.name,
"description": tax.description,
}
def _get_query_taxes(self):
@ -176,33 +179,37 @@ class JournalLedgerReport(models.AbstractModel):
def _get_query_taxes_params(self, move_lines):
return {
'move_line_ids': tuple(move_lines.ids),
"move_line_ids": tuple(move_lines.ids),
}
def _get_move_lines(self, move_ids, wizard, journal_ids):
move_lines = self.env['account.move.line'].search(
move_lines = self.env["account.move.line"].search(
self._get_move_lines_domain(move_ids, wizard, journal_ids),
order=self._get_move_lines_order(move_ids, wizard, journal_ids))
order=self._get_move_lines_order(move_ids, wizard, journal_ids),
)
# Get the taxes ids for the move lines
query_taxes_params = self._get_query_taxes_params(move_lines)
query_taxes = self._get_query_taxes()
move_line_ids_taxes_data = {}
self.env.cr.execute(query_taxes,
query_taxes_params)
self.env.cr.execute(query_taxes, query_taxes_params)
# Fetch the taxes associated to the move line
for move_line_id, account_tax_id, tax_description, tax_name in \
self.env.cr.fetchall():
for (
move_line_id,
account_tax_id,
tax_description,
tax_name,
) in self.env.cr.fetchall():
if move_line_id not in move_line_ids_taxes_data.keys():
move_line_ids_taxes_data[move_line_id] = {}
move_line_ids_taxes_data[move_line_id][account_tax_id] = {
'name': tax_name,
'description': tax_description
"name": tax_name,
"description": tax_description,
}
Move_Lines = {}
accounts = self.env['account.account']
partners = self.env['res.partner']
currencies = self.env['res.currency']
tax_lines = self.env['account.tax']
accounts = self.env["account.account"]
partners = self.env["res.partner"]
currencies = self.env["res.currency"]
tax_lines = self.env["account.tax"]
for ml in move_lines:
if ml.account_id not in accounts:
accounts |= ml.account_id
@ -214,137 +221,156 @@ class JournalLedgerReport(models.AbstractModel):
tax_lines |= ml.tax_line_id
if ml.move_id.id not in Move_Lines.keys():
Move_Lines[ml.move_id.id] = []
taxes = ml.id in move_line_ids_taxes_data.keys() and \
move_line_ids_taxes_data[ml.id] or {}
Move_Lines[ml.move_id.id].append(self._get_move_lines_data(
ml, wizard, taxes))
taxes = (
ml.id in move_line_ids_taxes_data.keys()
and move_line_ids_taxes_data[ml.id]
or {}
)
Move_Lines[ml.move_id.id].append(
self._get_move_lines_data(ml, wizard, taxes)
)
account_ids_data = self._get_account_data(accounts)
partner_ids_data = self._get_partner_data(partners)
currency_ids_data = self._get_currency_data(currencies)
tax_line_ids_data = self._get_tax_line_data(tax_lines)
return move_lines.ids, Move_Lines, account_ids_data, \
partner_ids_data, currency_ids_data, tax_line_ids_data, \
move_line_ids_taxes_data
return (
move_lines.ids,
Move_Lines,
account_ids_data,
partner_ids_data,
currency_ids_data,
tax_line_ids_data,
move_line_ids_taxes_data,
)
def _get_journal_tax_lines(self, wizard, moves_data):
journals_taxes_data = {}
for move_data in moves_data:
report_move_lines = move_data['report_move_lines']
report_move_lines = move_data["report_move_lines"]
for report_move_line in report_move_lines:
ml_data = report_move_line
tax_ids = []
if ml_data['tax_line_id']:
tax_ids.append(ml_data['tax_line_id'])
if ml_data['tax_ids']:
tax_ids += ml_data['tax_ids']
if ml_data["tax_line_id"]:
tax_ids.append(ml_data["tax_line_id"])
if ml_data["tax_ids"]:
tax_ids += ml_data["tax_ids"]
tax_ids = list(set(tax_ids))
journal_id = ml_data['journal_id']
journal_id = ml_data["journal_id"]
if journal_id not in journals_taxes_data.keys():
journals_taxes_data[journal_id] = {}
taxes = self.env['account.tax'].browse(tax_ids)
taxes = self.env["account.tax"].browse(tax_ids)
for tax in taxes:
if tax.id not in journals_taxes_data[journal_id]:
journals_taxes_data[journal_id][tax.id] = {
'base_debit': 0.0,
'base_credit': 0.0,
'base_balance': 0.0,
'tax_debit': 0.0,
'tax_credit': 0.0,
'tax_balance': 0.0,
'tax_name': tax.name,
'tax_code': tax.description,
"base_debit": 0.0,
"base_credit": 0.0,
"base_balance": 0.0,
"tax_debit": 0.0,
"tax_credit": 0.0,
"tax_balance": 0.0,
"tax_name": tax.name,
"tax_code": tax.description,
}
field_keys = ['base_debit', 'base_credit', 'base_balance',
'tax_debit', 'tax_credit', 'tax_balance',
]
field_keys = [
"base_debit",
"base_credit",
"base_balance",
"tax_debit",
"tax_credit",
"tax_balance",
]
for field_key in field_keys:
journals_taxes_data[journal_id][tax.id][field_key] += \
ml_data[field_key]
journals_taxes_data[journal_id][tax.id][field_key] += ml_data[
field_key
]
journals_taxes_data_2 = {}
for journal_id in journals_taxes_data.keys():
journals_taxes_data_2[journal_id] = []
for tax_id in journals_taxes_data[journal_id].keys():
journals_taxes_data_2[journal_id] += \
[journals_taxes_data[journal_id][tax_id]]
journals_taxes_data_2[journal_id] += [
journals_taxes_data[journal_id][tax_id]
]
return journals_taxes_data_2
@api.multi
def _get_report_values(self, docids, data):
wizard_id = data['wizard_id']
wizard = self.env['journal.ledger.report.wizard'].browse(wizard_id)
company = self.env['res.company'].browse(data['company_id'])
journal_ids = data['journal_ids']
journal_ledgers_data = self._get_journal_ledgers(
wizard, journal_ids, company)
move_ids, moves_data, move_ids_data = self._get_moves(
wizard, journal_ids)
wizard_id = data["wizard_id"]
wizard = self.env["journal.ledger.report.wizard"].browse(wizard_id)
company = self.env["res.company"].browse(data["company_id"])
journal_ids = data["journal_ids"]
journal_ledgers_data = self._get_journal_ledgers(wizard, journal_ids, company)
move_ids, moves_data, move_ids_data = self._get_moves(wizard, journal_ids)
journal_moves_data = {}
for key, items in itertools.groupby(
moves_data, operator.itemgetter('journal_id')):
moves_data, operator.itemgetter("journal_id")
):
if key not in journal_moves_data.keys():
journal_moves_data[key] = []
journal_moves_data[key] += list(items)
move_lines_data = account_ids_data = partner_ids_data = \
currency_ids_data = tax_line_ids_data = \
move_line_ids_taxes_data = {}
move_lines_data = (
account_ids_data
) = (
partner_ids_data
) = currency_ids_data = tax_line_ids_data = move_line_ids_taxes_data = {}
if move_ids:
move_line_ids, move_lines_data, account_ids_data, \
partner_ids_data, currency_ids_data, tax_line_ids_data, \
move_line_ids_taxes_data = self._get_move_lines(
move_ids, wizard, journal_ids)
(
move_line_ids,
move_lines_data,
account_ids_data,
partner_ids_data,
currency_ids_data,
tax_line_ids_data,
move_line_ids_taxes_data,
) = self._get_move_lines(move_ids, wizard, journal_ids)
for move_data in moves_data:
move_id = move_data['move_id']
move_data['report_move_lines'] = []
move_id = move_data["move_id"]
move_data["report_move_lines"] = []
if move_id in move_lines_data.keys():
move_data['report_move_lines'] += move_lines_data[move_id]
move_data["report_move_lines"] += move_lines_data[move_id]
journals_taxes_data = {}
if moves_data:
journals_taxes_data = self._get_journal_tax_lines(
wizard, moves_data)
journals_taxes_data = self._get_journal_tax_lines(wizard, moves_data)
for journal_ledger_data in journal_ledgers_data:
journal_id = journal_ledger_data['id']
journal_ledger_data['tax_lines'] = \
journals_taxes_data.get(journal_id, [])
journal_id = journal_ledger_data["id"]
journal_ledger_data["tax_lines"] = journals_taxes_data.get(journal_id, [])
journal_totals = {}
for move_id in move_lines_data.keys():
for move_line_data in move_lines_data[move_id]:
journal_id = move_line_data['journal_id']
journal_id = move_line_data["journal_id"]
if journal_id not in journal_totals.keys():
journal_totals[journal_id] = {
'debit': 0.0,
'credit': 0.0,
"debit": 0.0,
"credit": 0.0,
}
for item in ['debit', 'credit']:
for item in ["debit", "credit"]:
journal_totals[journal_id][item] += move_line_data[item]
for journal_ledger_data in journal_ledgers_data:
journal_id = journal_ledger_data['id']
journal_id = journal_ledger_data["id"]
if journal_id in journal_moves_data.keys():
journal_ledger_data['report_moves'] = \
journal_moves_data[journal_id]
journal_ledger_data["report_moves"] = journal_moves_data[journal_id]
else:
journal_ledger_data['report_moves'] = []
journal_ledger_data["report_moves"] = []
if journal_id in journal_totals.keys():
for item in ['debit', 'credit']:
journal_ledger_data[item] += \
journal_totals[journal_id][item]
for item in ["debit", "credit"]:
journal_ledger_data[item] += journal_totals[journal_id][item]
return {
'doc_ids': [wizard_id],
'doc_model': 'journal.ledger.report.wizard',
'docs': self.env['journal.ledger.report.wizard'].browse(wizard_id),
'group_option': data['group_option'],
'foreign_currency': data['foreign_currency'],
'with_account_name': data['with_account_name'],
'company_name': company.display_name,
'currency_name': company.currency_id.name,
'date_from': data['date_from'],
'date_to': data['date_to'],
'move_target': data['move_target'],
'account_ids_data': account_ids_data,
'partner_ids_data': partner_ids_data,
'currency_ids_data': currency_ids_data,
'move_ids_data': move_ids_data,
'tax_line_data': tax_line_ids_data,
'move_line_ids_taxes_data': move_line_ids_taxes_data,
'Journal_Ledgers': journal_ledgers_data,
'Moves': moves_data,
"doc_ids": [wizard_id],
"doc_model": "journal.ledger.report.wizard",
"docs": self.env["journal.ledger.report.wizard"].browse(wizard_id),
"group_option": data["group_option"],
"foreign_currency": data["foreign_currency"],
"with_account_name": data["with_account_name"],
"company_name": company.display_name,
"currency_name": company.currency_id.name,
"date_from": data["date_from"],
"date_to": data["date_to"],
"move_target": data["move_target"],
"account_ids_data": account_ids_data,
"partner_ids_data": partner_ids_data,
"currency_ids_data": currency_ids_data,
"move_ids_data": move_ids_data,
"tax_line_data": tax_line_ids_data,
"move_line_ids_taxes_data": move_line_ids_taxes_data,
"Journal_Ledgers": journal_ledgers_data,
"Moves": moves_data,
}

295
account_financial_report/report/journal_ledger_xlsx.py

@ -7,88 +7,51 @@ from odoo import _, models
class JournalLedgerXslx(models.AbstractModel):
_name = 'report.a_f_r.report_journal_ledger_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
_name = "report.a_f_r.report_journal_ledger_xlsx"
_inherit = "report.account_financial_report.abstract_report_xlsx"
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('Journal Ledger')
company_id = data.get("company_id", False)
report_name = _("Journal Ledger")
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
company = self.env["res.company"].browse(company_id)
suffix = " - {} - {}".format(company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
columns = [
{
'header': _('Entry'),
'field': 'entry',
'width': 18
},
{
'header': _('Date'),
'field': 'date',
'width': 11
},
{
'header': _('Account'),
'field': 'account_code',
'width': 9
},
{"header": _("Entry"), "field": "entry", "width": 18},
{"header": _("Date"), "field": "date", "width": 11},
{"header": _("Account"), "field": "account_code", "width": 9},
]
if report.with_account_name:
columns.append({
'header': _('Account Name'),
'field': 'account_name',
'width': 15
})
columns.append(
{"header": _("Account Name"), "field": "account_name", "width": 15}
)
columns += [
{
'header': _('Partner'),
'field': 'partner',
'width': 25
},
{
'header': _('Ref - Label'),
'field': 'label',
'width': 40
},
{
'header': _('Taxes'),
'field': 'taxes_description',
'width': 11
},
{
'header': _('Debit'),
'field': 'debit',
'type': 'amount',
'width': 14,
},
{
'header': _('Credit'),
'field': 'credit',
'type': 'amount',
'width': 14
}
{"header": _("Partner"), "field": "partner", "width": 25},
{"header": _("Ref - Label"), "field": "label", "width": 40},
{"header": _("Taxes"), "field": "taxes_description", "width": 11},
{"header": _("Debit"), "field": "debit", "type": "amount", "width": 14,},
{"header": _("Credit"), "field": "credit", "type": "amount", "width": 14},
]
if report.foreign_currency:
columns += [
{
'header': _('Currency'),
'field': 'currency_name',
'width': 14,
'type': 'currency_name',
"header": _("Currency"),
"field": "currency_name",
"width": 14,
"type": "currency_name",
},
{
'header': _('Amount Currency'),
'field': 'amount_currency',
'type': 'amount',
'width': 18
"header": _("Amount Currency"),
"field": "amount_currency",
"type": "amount",
"width": 18,
},
]
@ -99,51 +62,43 @@ class JournalLedgerXslx(models.AbstractModel):
def _get_journal_tax_columns(self, report):
return {
0: {
'header': _('Name'),
'field': 'tax_name',
'width': 35
},
1: {
'header': _('Description'),
'field': 'tax_code',
'width': 18
},
0: {"header": _("Name"), "field": "tax_name", "width": 35},
1: {"header": _("Description"), "field": "tax_code", "width": 18},
2: {
'header': _('Base Debit'),
'field': 'base_debit',
'type': 'amount',
'width': 14
"header": _("Base Debit"),
"field": "base_debit",
"type": "amount",
"width": 14,
},
3: {
'header': _('Base Credit'),
'field': 'base_credit',
'type': 'amount',
'width': 14
"header": _("Base Credit"),
"field": "base_credit",
"type": "amount",
"width": 14,
},
4: {
'header': _('Base Balance'),
'field': 'base_balance',
'type': 'amount',
'width': 14
"header": _("Base Balance"),
"field": "base_balance",
"type": "amount",
"width": 14,
},
5: {
'header': _('Tax Debit'),
'field': 'tax_debit',
'type': 'amount',
'width': 14
"header": _("Tax Debit"),
"field": "tax_debit",
"type": "amount",
"width": 14,
},
6: {
'header': _('Tax Credit'),
'field': 'tax_credit',
'type': 'amount',
'width': 14
"header": _("Tax Credit"),
"field": "tax_credit",
"type": "amount",
"width": 14,
},
7: {
'header': _('Tax Balance'),
'field': 'tax_balance',
'type': 'amount',
'width': 14
"header": _("Tax Balance"),
"field": "tax_balance",
"type": "amount",
"width": 14,
},
}
@ -156,92 +111,87 @@ class JournalLedgerXslx(models.AbstractModel):
def _get_report_filters(self, report):
target_label_by_value = {
value: label
for value, label in
self.env['journal.ledger.report.wizard']._get_move_targets()
for value, label in self.env[
"journal.ledger.report.wizard"
]._get_move_targets()
}
sort_option_label_by_value = {
value: label
for value, label in
self.env['journal.ledger.report.wizard']._get_sort_options()
for value, label in self.env[
"journal.ledger.report.wizard"
]._get_sort_options()
}
return [
[_("Company"), report.company_id.name],
[
_('Company'),
report.company_id.name
],
[
_('Date range filter'),
_('From: %s To: %s') % (report.date_from, report.date_to)
_("Date range filter"),
_("From: %s To: %s") % (report.date_from, report.date_to),
],
[
_('Target moves filter'),
_("Target moves filter"),
_("%s") % target_label_by_value[report.move_target],
],
[
_('Entries sorted by'),
_("Entries sorted by"),
_("%s") % sort_option_label_by_value[report.sort_option],
],
[
_('Journals'),
', '.join([
"%s - %s" % (report_journal.code, report_journal.name)
for report_journal in report.journal_ids
])
]
_("Journals"),
", ".join(
[
"{} - {}".format(report_journal.code, report_journal.name)
for report_journal in report.journal_ids
]
),
],
]
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.journal_ledger'
"report.account_financial_report.journal_ledger"
]._get_report_values(report, data)
group_option = report.group_option
if group_option == 'journal':
for ledger in res_data['Journal_Ledgers']:
self._generate_journal_content(workbook, report, res_data,
ledger)
elif group_option == 'none':
self._generate_no_group_content(workbook, report,
res_data)
if group_option == "journal":
for ledger in res_data["Journal_Ledgers"]:
self._generate_journal_content(workbook, report, res_data, ledger)
elif group_option == "none":
self._generate_no_group_content(workbook, report, res_data)
def _generate_no_group_content(self, workbook, report, res_data):
self._generate_moves_content(
workbook, "Report", report, res_data, res_data['Moves'])
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, 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" % (
journal.code,
currency_name,
journal.name,
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 = "{} ({}) - {}".format(journal.code, currency_name, journal.name)
self._generate_moves_content(
workbook, sheet_name, report, res_data, ledger['report_moves'])
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, res_data):
self._generate_taxes_summary(
workbook, "Tax Report", res_data['tax_line_data'])
self._generate_taxes_summary(workbook, "Tax Report", res_data["tax_line_data"])
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" % (
journal.code,
currency_name,
journal.name,
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
)
self._generate_taxes_summary(
workbook, sheet_name, ledger['tax_lines'])
sheet_name = "Tax - {} ({}) - {}".format(journal.code, currency_name, journal.name)
self._generate_taxes_summary(workbook, sheet_name, ledger["tax_lines"])
def _generate_moves_content(self, workbook, sheet_name, report, res_data,
moves):
def _generate_moves_content(self, workbook, sheet_name, report, res_data, moves):
self.workbook = workbook
self.sheet = workbook.add_worksheet(sheet_name)
self._set_column_width()
@ -252,32 +202,33 @@ class JournalLedgerXslx(models.AbstractModel):
self.row_pos += 2
self.write_array_header()
account_ids_data = res_data['account_ids_data']
partner_ids_data = res_data['partner_ids_data']
currency_ids_data = res_data['currency_ids_data']
move_ids_data = res_data['move_ids_data']
account_ids_data = res_data["account_ids_data"]
partner_ids_data = res_data["partner_ids_data"]
currency_ids_data = res_data["currency_ids_data"]
move_ids_data = res_data["move_ids_data"]
for move in moves:
for line in move['report_move_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))
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
@ -291,6 +242,6 @@ class JournalLedgerXslx(models.AbstractModel):
def _get_partner_name(self, partner_id, partner_data):
if partner_id in partner_data.keys():
return partner_data[partner_id]['name']
return partner_data[partner_id]["name"]
else:
return ''
return ""

390
account_financial_report/report/open_items.py

@ -2,15 +2,17 @@
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, api
from odoo.tools import float_is_zero
from odoo.osv import expression
from datetime import date, datetime
import pandas as pd
from odoo import api, models
from odoo.osv import expression
from odoo.tools import float_is_zero
class OpenItemsReport(models.AbstractModel):
_name = 'report.account_financial_report.open_items'
_name = "report.account_financial_report.open_items"
@api.model
def get_html(self, given_context=None):
@ -20,77 +22,115 @@ class OpenItemsReport(models.AbstractModel):
result = {}
rcontext = {}
context = dict(self.env.context)
rcontext.update(context.get('data'))
active_id = context.get('active_id')
wiz = self.env['open.items.report.wizard'].browse(active_id)
rcontext['o'] = wiz
result['html'] = self.env.ref(
'account_financial_report.report_open_items').render(rcontext)
rcontext.update(context.get("data"))
active_id = context.get("active_id")
wiz = self.env["open.items.report.wizard"].browse(active_id)
rcontext["o"] = wiz
result["html"] = self.env.ref(
"account_financial_report.report_open_items"
).render(rcontext)
return result
def _get_account_partial_reconciled(self, move_lines_data, date_at_object):
reconciled_ids = []
for move_line in move_lines_data:
if move_line['reconciled']:
reconciled_ids += [move_line['id']]
domain = [('max_date', '>=', date_at_object)]
if move_line["reconciled"]:
reconciled_ids += [move_line["id"]]
domain = [("max_date", ">=", date_at_object)]
domain += expression.OR(
[[('debit_move_id', 'in', reconciled_ids)],
[('credit_move_id', 'in', reconciled_ids)]])
fields = ['debit_move_id', 'credit_move_id', 'amount']
accounts_partial_reconcile = \
self.env['account.partial.reconcile'].search_read(
domain=domain,
fields=fields
)
[
[("debit_move_id", "in", reconciled_ids)],
[("credit_move_id", "in", reconciled_ids)],
]
)
fields = ["debit_move_id", "credit_move_id", "amount"]
accounts_partial_reconcile = self.env["account.partial.reconcile"].search_read(
domain=domain, fields=fields
)
debit_accounts_partial_amount = {}
credit_accounts_partial_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]
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_accounts_partial_amount.keys():
debit_accounts_partial_amount[debit_move_id] = 0.0
debit_accounts_partial_amount[debit_move_id] += \
account_partial_reconcile_data['amount']
debit_accounts_partial_amount[
debit_move_id
] += account_partial_reconcile_data["amount"]
if credit_move_id not in credit_accounts_partial_amount.keys():
credit_accounts_partial_amount[credit_move_id] = 0.0
credit_accounts_partial_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_accounts_partial_amount, \
credit_accounts_partial_amount
credit_accounts_partial_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_accounts_partial_amount,
credit_accounts_partial_amount,
)
@api.model
def _get_query_domain(self, account_ids, partner_ids, date_at_object,
target_move, company_id, date_from):
def _get_query_domain(
self,
account_ids,
partner_ids,
date_at_object,
target_move,
company_id,
date_from,
):
query = """
WHERE aml.account_id in %s and aml.company_id = %s
""" % (tuple(account_ids) if len(account_ids) > 1 else "(%s)" %
account_ids[0], company_id)
""" % (
tuple(account_ids) if len(account_ids) > 1 else "(%s)" % account_ids[0],
company_id,
)
if date_from:
query += " and aml.date >= '%s'" % date_from
if partner_ids:
query += " and aml.partner_id in %s" % (tuple(partner_ids),)
if target_move == 'posted':
query += " and aml.partner_id in {}".format(tuple(partner_ids))
if target_move == "posted":
query += " and am.state = 'posted'"
if date_at_object >= date.today():
query += " and aml.reconciled IS FALSE"
else:
query += """ and ((aml.reconciled IS FALSE OR aml.date >= '%s')
OR aml.full_reconcile_id IS NOT NULL)""" % date_at_object
query += (
""" and ((aml.reconciled IS FALSE OR aml.date >= '%s')
OR aml.full_reconcile_id IS NOT NULL)"""
% date_at_object
)
return query
@api.model
def _get_query(self, account_ids, partner_ids, date_at_object,
target_move, company_id, date_from):
def _get_query(
self,
account_ids,
partner_ids,
date_at_object,
target_move,
company_id,
date_from,
):
aml_fields = [
'id', 'date', 'move_id', 'journal_id', 'account_id', 'partner_id',
'ref', 'date_maturity', 'amount_residual', 'amount_currency',
'amount_residual_currency', 'debit', 'credit', 'currency_id',
'reconciled', 'full_reconcile_id']
"id",
"date",
"move_id",
"journal_id",
"account_id",
"partner_id",
"ref",
"date_maturity",
"amount_residual",
"amount_currency",
"amount_residual_currency",
"debit",
"credit",
"currency_id",
"reconciled",
"full_reconcile_id",
]
query = ""
# SELECT
@ -118,178 +158,208 @@ class OpenItemsReport(models.AbstractModel):
"""
# WHERE
query += self._get_query_domain(account_ids, partner_ids,
date_at_object, target_move,
company_id, date_from)
query += self._get_query_domain(
account_ids, partner_ids, date_at_object, target_move, company_id, date_from
)
return query
def _get_accounts_data(self, accounts_ids):
accounts = self.env['account.account'].browse(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,
'hide_account': False,
'currency_id': account.currency_id or False,
'currency_name': account.currency_id.name}
})
accounts_data.update(
{
account.id: {
"id": account.id,
"code": account.code,
"name": account.name,
"hide_account": False,
"currency_id": account.currency_id or False,
"currency_name": account.currency_id.name,
}
}
)
return accounts_data
def _get_journals_data(self, journals_ids):
journals = self.env['account.journal'].browse(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}})
journals_data.update({journal.id: {"id": journal.id, "code": journal.code}})
return journals_data
def _get_data(self, account_ids, partner_ids, date_at_object, target_move,
company_id, date_from):
query = self._get_query(account_ids, partner_ids, date_at_object,
target_move, company_id, date_from)
def _get_data(
self,
account_ids,
partner_ids,
date_at_object,
target_move,
company_id,
date_from,
):
query = self._get_query(
account_ids, partner_ids, date_at_object, target_move, company_id, date_from
)
self._cr.execute(query)
move_lines_data = pd.DataFrame(self._cr.dictfetchall())
account_ids = set(move_lines_data.account_id.to_list())
accounts_data = self._get_accounts_data(list(account_ids))
journal_ids = set(move_lines_data.journal_id.to_list())
journals_data = self._get_journals_data(list(journal_ids))
move_lines_data = move_lines_data.fillna(0).to_dict(orient='records')
move_lines_data = move_lines_data.fillna(0).to_dict(orient="records")
if date_at_object < date.today():
accounts_partial_reconcile, debit_accounts_partial_amount, \
credit_accounts_partial_amount = \
self._get_account_partial_reconciled(move_lines_data,
date_at_object)
(
accounts_partial_reconcile,
debit_accounts_partial_amount,
credit_accounts_partial_amount,
) = self._get_account_partial_reconciled(move_lines_data, date_at_object)
if accounts_partial_reconcile:
accounts_partial_reconcile_data = pd.DataFrame(
accounts_partial_reconcile)
debit_ids = set(accounts_partial_reconcile_data.debit_move_id
.to_list())
accounts_partial_reconcile
)
debit_ids = set(accounts_partial_reconcile_data.debit_move_id.to_list())
credit_ids = set(
accounts_partial_reconcile_data.credit_move_id.to_list())
accounts_partial_reconcile_data.credit_move_id.to_list()
)
for move_line in move_lines_data:
if move_line['id'] in debit_ids:
move_line['amount_residual'] += \
debit_accounts_partial_amount[move_line['id']]
if move_line['id'] in credit_ids:
move_line['amount_residual'] -= \
credit_accounts_partial_amount[move_line['id']]
if move_line["id"] in debit_ids:
move_line["amount_residual"] += debit_accounts_partial_amount[
move_line["id"]
]
if move_line["id"] in credit_ids:
move_line["amount_residual"] -= credit_accounts_partial_amount[
move_line["id"]
]
moves_lines_to_remove = []
for move_line in move_lines_data:
if move_line['date'] > date_at_object or float_is_zero(
move_line['amount_residual'], precision_digits=2):
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_data.remove(move_line_to_remove)
partners_data = {
0: {
'id': 0,
'name': 'Missing Partner'
}
}
partners_data = {0: {"id": 0, "name": "Missing Partner"}}
open_items_move_lines_data = {}
for move_line in move_lines_data:
no_partner = True
# Partners data
if move_line['partner_id'] and not pd.isna(move_line['partner_id']):
if move_line["partner_id"] and not pd.isna(move_line["partner_id"]):
no_partner = False
partners_data.update({
move_line['partner_id']: {
'id': move_line['partner_id'],
'name': move_line['partner_name'],
'currency_id': accounts_data[move_line[
'account_id']]['currency_id'],
partners_data.update(
{
move_line["partner_id"]: {
"id": move_line["partner_id"],
"name": move_line["partner_name"],
"currency_id": accounts_data[move_line["account_id"]][
"currency_id"
],
}
}
})
)
else:
partners_data[0]['currency_id'] = accounts_data[move_line[
'account_id']]['currency_id']
partners_data[0]["currency_id"] = accounts_data[
move_line["account_id"]
]["currency_id"]
# Move line update
original = 0
if not float_is_zero(move_line['credit'], precision_digits=2):
original = move_line['credit']*(-1)
if not float_is_zero(move_line['debit'], precision_digits=2):
original = move_line['debit']
if not float_is_zero(move_line["credit"], precision_digits=2):
original = move_line["credit"] * (-1)
if not float_is_zero(move_line["debit"], precision_digits=2):
original = move_line["debit"]
move_line.update({
'date': move_line['date'].strftime("%d/%m/%Y"),
'date_maturity': move_line['date_maturity'].strftime("%d/%m/%Y"),
'original': original,
'partner_id': 0 if no_partner else move_line['partner_id'],
'partner_name': '' if no_partner else move_line['partner_name'],
'ref': '' if not move_line['ref'] else move_line['ref'],
'account': accounts_data[move_line['account_id']]['code'],
'journal': journals_data[move_line['journal_id']]['code'],
})
move_line.update(
{
"date": move_line["date"].strftime("%d/%m/%Y"),
"date_maturity": move_line["date_maturity"].strftime("%d/%m/%Y"),
"original": original,
"partner_id": 0 if no_partner else move_line["partner_id"],
"partner_name": "" if no_partner else move_line["partner_name"],
"ref": "" if not move_line["ref"] else move_line["ref"],
"account": accounts_data[move_line["account_id"]]["code"],
"journal": journals_data[move_line["journal_id"]]["code"],
}
)
# Open Items Move Lines Data
if move_line['account_id'] not in open_items_move_lines_data.keys():
open_items_move_lines_data[move_line['account_id']] = {
move_line['partner_id']: [move_line]}
if move_line["account_id"] not in open_items_move_lines_data.keys():
open_items_move_lines_data[move_line["account_id"]] = {
move_line["partner_id"]: [move_line]
}
else:
if move_line['partner_id'] not in \
open_items_move_lines_data[move_line[
'account_id']].keys():
open_items_move_lines_data[move_line['account_id']][
move_line['partner_id']] = [move_line]
if (
move_line["partner_id"]
not in open_items_move_lines_data[move_line["account_id"]].keys()
):
open_items_move_lines_data[move_line["account_id"]][
move_line["partner_id"]
] = [move_line]
else:
open_items_move_lines_data[move_line['account_id']][
move_line['partner_id']].append(move_line)
return move_lines_data, partners_data, journals_data, accounts_data, \
open_items_move_lines_data
open_items_move_lines_data[move_line["account_id"]][
move_line["partner_id"]
].append(move_line)
return (
move_lines_data,
partners_data,
journals_data,
accounts_data,
open_items_move_lines_data,
)
@api.model
def _calculate_amounts(self, open_items_move_lines_data):
total_amount = {}
for account_id in open_items_move_lines_data.keys():
total_amount[account_id] = {}
total_amount[account_id]['residual'] = 0.0
total_amount[account_id]["residual"] = 0.0
for partner_id in open_items_move_lines_data[account_id].keys():
total_amount[account_id][partner_id] = {}
total_amount[account_id][partner_id]['residual'] = 0.0
for move_line in open_items_move_lines_data[account_id][
partner_id]:
total_amount[account_id][partner_id]['residual'] += \
move_line['amount_residual']
total_amount[account_id]['residual'] += move_line[
'amount_residual']
total_amount[account_id][partner_id]["residual"] = 0.0
for move_line in open_items_move_lines_data[account_id][partner_id]:
total_amount[account_id][partner_id]["residual"] += move_line[
"amount_residual"
]
total_amount[account_id]["residual"] += move_line["amount_residual"]
return total_amount
@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()
date_from = data['date_from']
target_move = data['target_move']
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()
date_from = data["date_from"]
target_move = data["target_move"]
move_lines_data, partners_data, journals_data, accounts_data, \
open_items_move_lines_data = self._get_data(
account_ids, partner_ids, date_at_object,
target_move, company_id, date_from)
(
move_lines_data,
partners_data,
journals_data,
accounts_data,
open_items_move_lines_data,
) = self._get_data(
account_ids, partner_ids, date_at_object, target_move, company_id, date_from
)
total_amount = self._calculate_amounts(open_items_move_lines_data)
return{
'doc_ids': [wizard_id],
'doc_model': 'open.items.report.wizard',
'docs': self.env['open.items.report.wizard'].browse(wizard_id),
'foreign_currency': data['foreign_currency'],
'company_name': company.display_name,
'currency_name': company.currency_id.name,
'date_at': date_at_object.strftime("%d/%m/%Y"),
'hide_account_at_0': data['hide_account_at_0'],
'target_move': data['target_move'],
'partners_data': partners_data,
'accounts_data': accounts_data,
'total_amount': total_amount,
'Open_Items': open_items_move_lines_data,
return {
"doc_ids": [wizard_id],
"doc_model": "open.items.report.wizard",
"docs": self.env["open.items.report.wizard"].browse(wizard_id),
"foreign_currency": data["foreign_currency"],
"company_name": company.display_name,
"currency_name": company.currency_id.name,
"date_at": date_at_object.strftime("%d/%m/%Y"),
"hide_account_at_0": data["hide_account_at_0"],
"target_move": data["target_move"],
"partners_data": partners_data,
"accounts_data": accounts_data,
"total_amount": total_amount,
"Open_Items": open_items_move_lines_data,
}

176
account_financial_report/report/open_items_xlsx.py

@ -6,70 +6,85 @@ from odoo import _, models
class OpenItemsXslx(models.AbstractModel):
_name = 'report.a_f_r.report_open_items_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
_name = "report.a_f_r.report_open_items_xlsx"
_inherit = "report.account_financial_report.abstract_report_xlsx"
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('Open Items')
company_id = data.get("company_id", False)
report_name = _("Open Items")
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
company = self.env["res.company"].browse(company_id)
suffix = " - {} - {}".format(company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
res = {
0: {'header': _('Date'), 'field': 'date', 'width': 11},
1: {'header': _('Entry'), 'field': 'move_id_name', 'width': 18},
2: {'header': _('Journal'), 'field': 'journal', 'width': 8},
3: {'header': _('Account'), 'field': 'account', 'width': 9},
4: {'header': _('Partner'), 'field': 'partner', 'width': 25},
5: {'header': _('Ref - Label'), 'field': 'ref', 'width': 40},
6: {'header': _('Due date'), 'field': 'date_maturity', 'width': 11},
7: {'header': _('Original'),
'field': 'original',
'type': 'amount',
'width': 14},
8: {'header': _('Residual'),
'field': 'amount_residual',
'field_final_balance': 'residual',
'type': 'amount',
'width': 14},
0: {"header": _("Date"), "field": "date", "width": 11},
1: {"header": _("Entry"), "field": "move_id_name", "width": 18},
2: {"header": _("Journal"), "field": "journal", "width": 8},
3: {"header": _("Account"), "field": "account", "width": 9},
4: {"header": _("Partner"), "field": "partner", "width": 25},
5: {"header": _("Ref - Label"), "field": "ref", "width": 40},
6: {"header": _("Due date"), "field": "date_maturity", "width": 11},
7: {
"header": _("Original"),
"field": "original",
"type": "amount",
"width": 14,
},
8: {
"header": _("Residual"),
"field": "amount_residual",
"field_final_balance": "residual",
"type": "amount",
"width": 14,
},
}
if report.foreign_currency:
foreign_currency = {
9: {'header': _('Cur.'), 'field': 'currency_name',
'field_currency_balance': 'currency_name',
'type': 'currency_name',
'width': 7},
10: {'header': _('Cur. Original'),
'field': 'amount_currency',
'field_final_balance':
'amount_currency',
'type': 'amount_currency',
'width': 14},
11: {'header': _('Cur. Residual'),
'field': 'amount_residual_currency',
'field_final_balance':
'amount_currency',
'type': 'amount_currency',
'width': 14},
9: {
"header": _("Cur."),
"field": "currency_name",
"field_currency_balance": "currency_name",
"type": "currency_name",
"width": 7,
},
10: {
"header": _("Cur. Original"),
"field": "amount_currency",
"field_final_balance": "amount_currency",
"type": "amount_currency",
"width": 14,
},
11: {
"header": _("Cur. Residual"),
"field": "amount_residual_currency",
"field_final_balance": "amount_currency",
"type": "amount_currency",
"width": 14,
},
}
res = {**res, **foreign_currency}
return res
def _get_report_filters(self, report):
return [
[_('Date at filter'), report.date_at.strftime("%d/%m/%Y")],
[_('Target moves filter'),
_('All posted entries') if report.target_move == 'posted' else _(
'All entries')],
[_('Account balance at 0 filter'),
_('Hide') if report.hide_account_at_0 else _('Show')],
[_('Show foreign currency'),
_('Yes') if report.foreign_currency else _('No')],
[_("Date at filter"), report.date_at.strftime("%d/%m/%Y")],
[
_("Target moves filter"),
_("All posted entries")
if report.target_move == "posted"
else _("All entries"),
],
[
_("Account balance at 0 filter"),
_("Hide") if report.hide_account_at_0 else _("Show"),
],
[
_("Show foreign currency"),
_("Yes") if report.foreign_currency else _("No"),
],
]
def _get_col_count_filter_name(self):
@ -86,24 +101,27 @@ class OpenItemsXslx(models.AbstractModel):
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.open_items']._get_report_values(
report, data)
"report.account_financial_report.open_items"
]._get_report_values(report, data)
# For each account
Open_items = res_data['Open_Items']
accounts_data = res_data['accounts_data']
partners_data = res_data['partners_data']
total_amount = res_data['total_amount']
Open_items = res_data["Open_Items"]
accounts_data = res_data["accounts_data"]
partners_data = res_data["partners_data"]
total_amount = res_data["total_amount"]
for account_id in Open_items.keys():
# Write account title
self.write_array_title(accounts_data[account_id]['code'] + ' - ' +
accounts_data[account_id]['name'])
self.write_array_title(
accounts_data[account_id]["code"]
+ " - "
+ accounts_data[account_id]["name"]
)
# For each partner
if Open_items[account_id]:
for partner_id in Open_items[account_id]:
type_object = 'partner'
type_object = "partner"
# Write partner title
self.write_array_title(partners_data[partner_id]['name'])
self.write_array_title(partners_data[partner_id]["name"])
# Display array header for move lines
self.write_array_header()
@ -114,35 +132,37 @@ class OpenItemsXslx(models.AbstractModel):
# Display ending balance line for partner
self.write_ending_balance_from_dict(
partners_data[partner_id], type_object, total_amount,
account_id, partner_id)
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)
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):
def write_ending_balance_from_dict(
self, my_object, type_object, total_amount, account_id=False, partner_id=False
):
"""Specific function to write ending balance for Open Items"""
if type_object == 'partner':
name = my_object['name']
my_object['residual'] = total_amount[account_id][partner_id][
'residual']
label = _('Partner ending balance')
elif type_object == 'account':
name = my_object['code'] + ' - ' + my_object['name']
my_object['residual'] = total_amount[account_id][
'residual']
label = _('Ending balance')
if type_object == "partner":
name = my_object["name"]
my_object["residual"] = total_amount[account_id][partner_id]["residual"]
label = _("Partner ending balance")
elif type_object == "account":
name = my_object["code"] + " - " + my_object["name"]
my_object["residual"] = total_amount[account_id]["residual"]
label = _("Ending balance")
super(OpenItemsXslx, self).write_ending_balance_from_dict(
my_object, name, label)
my_object, name, label
)

589
account_financial_report/report/templates/aged_partner_balance.xml

@ -1,85 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="aged_partner_balance">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
<t t-call="account_financial_report.report_aged_partner_balance_base"/>
<t
t-call="account_financial_report.report_aged_partner_balance_base"
/>
</t>
</t>
</t>
</template>
<template id="report_aged_partner_balance_base">
<!-- Saved flag fields into variables, used to define columns display -->
<t t-set="show_move_line_details" t-value="show_move_line_details"/>
<t t-set="show_move_line_details" t-value="show_move_line_details" />
<!-- Defines global variables used by internal layout -->
<t t-set="title">Aged Partner Balance - <t t-raw="company_name"/> - <t t-raw="currency_name"/></t>
<t t-set="title">Aged Partner Balance - <t t-raw="company_name" /> - <t
t-raw="currency_name"
/></t>
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
<h4
class="mt0"
t-esc="title or 'Odoo Report'"
style="text-align: center;"
/>
</div>
<!-- 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="aged_partner_balance" t-as="account">
<div class="page_break">
<!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;"/>
<div class="act_as_caption account_title"
style="width: 100%;">
<span t-esc="account['code']"/>
<div class="act_as_table list_table" style="margin-top: 10px;" />
<div class="act_as_caption account_title" style="width: 100%;">
<span t-esc="account['code']" />
-
<span t-esc="account['name']"/>
<span t-esc="account['name']" />
</div>
<!-- Display account lines -->
<t t-if="not show_move_line_details">
<div class="act_as_table data_table"
style="width: 100%;">
<div class="act_as_table data_table" style="width: 100%;">
<!-- 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['partners']" t-as="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>
</div>
<!-- Display account footer -->
<t t-call="account_financial_report.report_aged_partner_balance_account_ending_cumul"/>
<t
t-call="account_financial_report.report_aged_partner_balance_account_ending_cumul"
/>
</t>
<!-- Display account move lines -->
<t t-if="show_move_line_details">
<!-- Display account partners -->
<t t-foreach="account['partners']" t-as="partner">
<div class="page_break">
<!-- Display partner header -->
<div class="act_as_caption account_title">
<span t-esc="partner['name']"/>
<span t-esc="partner['name']" />
</div>
<!-- Display partner move lines -->
<t t-call="account_financial_report.report_aged_partner_balance_move_lines"/>
<t
t-call="account_financial_report.report_aged_partner_balance_move_lines"
/>
<!-- Display partner footer -->
<t t-call="account_financial_report.report_aged_partner_balance_partner_ending_cumul">
<t t-set="partner_cumul_line" t-value="partner"/>
<t
t-call="account_financial_report.report_aged_partner_balance_partner_ending_cumul"
>
<t t-set="partner_cumul_line" t-value="partner" />
</t>
</div>
</t>
<!-- Display account footer -->
<t t-call="account_financial_report.report_aged_partner_balance_account_ending_cumul"/>
<t
t-call="account_financial_report.report_aged_partner_balance_account_ending_cumul"
/>
</t>
</div>
</t>
</div>
</template>
<template id="report_aged_partner_balance_filters">
<div class="act_as_table data_table" style="width: 100%;">
<div class="act_as_row labels">
@ -88,7 +94,7 @@
</div>
<div class="act_as_row">
<div class="act_as_cell">
<span t-esc="date_at"/>
<span t-esc="date_at" />
</div>
<div class="act_as_cell">
<t t-if="only_posted_moves">All posted entries</t>
@ -97,7 +103,6 @@
</div>
</div>
</template>
<template id="report_aged_partner_balance_lines_header">
<!-- Display table headers for lines -->
<div class="act_as_thead">
@ -121,45 +126,64 @@
</div>
</div>
</template>
<template id="report_aged_partner_balance_lines">
<!-- Display each partner lines -->
<div class="act_as_row lines">
<!--## partner-->
<div class="act_as_cell left">
<span t-esc="partner['name']"/>
<span t-esc="partner['name']" />
</div>
<!--## amount_residual-->
<div class="act_as_cell amount">
<span t-esc="partner['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<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}"/>
<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}"/>
<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}"/>
<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}"/>
<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}"/>
<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}"/>
<span
t-esc="partner['older']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
</div>
</template>
<template id="report_aged_partner_balance_move_lines">
<div class="act_as_table data_table" style="width: 100%;">
<!-- Display table headers for move lines -->
@ -210,195 +234,215 @@
<div class="act_as_row lines">
<!--## date-->
<div class="act_as_cell left">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.id"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line['date']" t-options="{'widget': 'date'}"/>
<!-- </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;">-->
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line['date']" t-options="{'widget': 'date'}" />
<!-- </a>-->
<!-- </span>-->
</div>
<!--## move-->
<div class="act_as_cell left">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.move_id.id"-->
<!-- t-att-data-res-model="'account.move'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['entry']"/>
<!-- </a>-->
<!-- </span>-->
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.move_id.id"-->
<!-- t-att-data-res-model="'account.move'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['entry']" />
<!-- </a>-->
<!-- </span>-->
</div>
<!--## journal-->
<div class="act_as_cell left">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.move_id.journal_id.id"-->
<!-- t-att-data-res-model="'account.journal'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['journal']"/>
<!-- </a>-->
<!-- </span>-->
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.move_id.journal_id.id"-->
<!-- t-att-data-res-model="'account.journal'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['journal']" />
<!-- </a>-->
<!-- </span>-->
</div>
<!--## account code-->
<div class="act_as_cell left">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.account_id.id"-->
<!-- t-att-data-res-model="'account.account'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['account']"/>
<!-- </a>-->
<!-- </span>-->
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.account_id.id"-->
<!-- t-att-data-res-model="'account.account'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['account']" />
<!-- </a>-->
<!-- </span>-->
</div>
<!--## partner-->
<div class="act_as_cell left">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.partner_id.id"-->
<!-- t-att-data-res-model="'res.partner'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['partner']"/>
<!-- </a>-->
<!-- </span>-->
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.partner_id.id"-->
<!-- t-att-data-res-model="'res.partner'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['partner']" />
<!-- </a>-->
<!-- </span>-->
</div>
<!--## ref - label-->
<div class="act_as_cell left">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.id"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['ref']"/>
<!-- </a>-->
<!-- </span>-->
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.id"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<t t-raw="line['ref']" />
<!-- </a>-->
<!-- </span>-->
</div>
<!--## date_due-->
<div class="act_as_cell left">
<!-- <span>-->
<!-- <a t-att-data-active-id="line.move_line_id.id"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- style="color: black;">-->
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line['due_date']" t-options="{'widget': 'date'}"/>
<!-- </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;">-->
<!--## We don't use t-field because it throws an error on click -->
<t t-esc="line['due_date']" t-options="{'widget': 'date'}" />
<!-- </a>-->
<!-- </span>-->
</div>
<!--## amount_residual-->
<div class="act_as_cell amount">
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t
t-raw="line['residual']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
</div>
<!--## current-->
<div class="act_as_cell amount">
<!-- <t t-if="line.current != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.current == 0">-->
<!-- <span t-field="line.current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
<!-- <t t-if="line.current != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t
t-raw="line['current']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.current == 0">-->
<!-- <span t-field="line.current" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## age_30_days-->
<div class="act_as_cell amount">
<!-- <t t-if="line.age_30_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_30_days == 0">-->
<!-- <span t-field="line.age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
<!-- <t t-if="line.age_30_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t
t-raw="line['30_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_30_days == 0">-->
<!-- <span t-field="line.age_30_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## age_60_days-->
<div class="act_as_cell amount">
<!-- <t t-if="line.age_60_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_60_days == 0">-->
<!-- <span t-field="line.age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
<!-- <t t-if="line.age_60_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t
t-raw="line['60_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_60_days == 0">-->
<!-- <span t-field="line.age_60_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## age_90_days-->
<div class="act_as_cell amount">
<!-- <t t-if="line.age_90_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_90_days == 0">-->
<!-- <span t-field="line.age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
<!-- <t t-if="line.age_90_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t
t-raw="line['90_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_90_days == 0">-->
<!-- <span t-field="line.age_90_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## age_120_days-->
<div class="act_as_cell amount">
<!-- <t t-if="line.age_120_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_120_days == 0">-->
<!-- <span t-field="line.age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
<!-- <t t-if="line.age_120_days != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t
t-raw="line['120_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.age_120_days == 0">-->
<!-- <span t-field="line.age_120_days" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
<!--## older-->
<div class="act_as_cell amount">
<!-- <t t-if="line.older != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t t-raw="line['older']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.older == 0">-->
<!-- <span t-field="line.older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
<!-- <t t-if="line.older != 0">-->
<!-- <span>-->
<!-- <a t-att-data-domain="[('id', 'in', (line.move_line_id | line.move_line_id.matched_debit_ids.mapped('debit_move_id') | line.move_line_id.matched_credit_ids.mapped('credit_move_id')).ids)]"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- style="color: black;">-->
<t
t-raw="line['older']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
<!-- </t>-->
<!-- <t t-if="line.older == 0">-->
<!-- <span t-field="line.older" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>-->
<!-- </t>-->
</div>
</div>
</t>
</div>
</template>
<template id="report_aged_partner_balance_partner_ending_cumul">
<!-- Display ending balance line for partner -->
<div class="act_as_table list_table" style="width: 100%;">
@ -407,39 +451,59 @@
<div class="act_as_cell right" style="width: 52.00%;">Partner
cumul aged balance</div>
<!--## date_due-->
<div class="act_as_cell" style="width: 6.00%;"/>
<div class="act_as_cell" style="width: 6.00%;" />
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-esc="partner_cumul_line['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="partner_cumul_line['residual']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## current-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-esc="partner_cumul_line['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="partner_cumul_line['current']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-esc="partner_cumul_line['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="partner_cumul_line['30_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-esc="partner_cumul_line['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="partner_cumul_line['60_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-esc="partner_cumul_line['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="partner_cumul_line['90_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-esc="partner_cumul_line['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="partner_cumul_line['120_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 6.00%;">
<span t-esc="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>
</template>
<template id="report_aged_partner_balance_account_ending_cumul">
<!-- Display ending balance line for account -->
<div class="act_as_table list_table" style="width: 100%;">
@ -449,65 +513,107 @@
<div class="act_as_cell right" style="width: 32.52%;">Total</div>
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-esc="account['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['residual']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## current-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-esc="account['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['current']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-esc="account['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['30_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-esc="account['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['60_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-esc="account['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['90_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-esc="account['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['120_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 9.64%;">
<span t-esc="account['older']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['older']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
</t>
<t t-if="show_move_line_details">
<!--## total-->
<div class="act_as_cell right" style="width: 52.00%;">Total</div>
<!--## date_due-->
<div class="act_as_cell" style="width: 6.00%;"/>
<div class="act_as_cell" style="width: 6.00%;" />
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-esc="account['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['residual']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## current-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-esc="account['current']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['current']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-esc="account['30_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['30_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-esc="account['60_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['60_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-esc="account['90_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['90_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-esc="account['120_days']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['120_days']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 6.00%">
<span t-esc="account['older']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="account['older']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
</t>
</div>
@ -517,24 +623,36 @@
<div class="act_as_cell right" style="width: 32.52%;">
Percents</div>
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 9.64%;"/>
<div class="act_as_cell amount" style="width: 9.64%;" />
<!--## current-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_current']"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span
t-esc="account['percent_current']"
/>%
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_30_days']"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span
t-esc="account['percent_30_days']"
/>%
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_60_days']"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span
t-esc="account['percent_60_days']"
/>%
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_90_days']"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span
t-esc="account['percent_90_days']"
/>%
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_120_days']"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span
t-esc="account['percent_120_days']"
/>%
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 9.64%;"><span t-esc="account['percent_older']"/>%
<div class="act_as_cell amount" style="width: 9.64%;"><span
t-esc="account['percent_older']"
/>%
</div>
</t>
<t t-if="show_move_line_details">
@ -542,30 +660,41 @@
<div class="act_as_cell right" style="width: 52.00%;">
Percents</div>
<!--## date_due-->
<div class="act_as_cell" style="width: 6.00%;"/>
<div class="act_as_cell" style="width: 6.00%;" />
<!--## amount_residual-->
<div class="act_as_cell amount" style="width: 6.00%"/>
<div class="act_as_cell amount" style="width: 6.00%" />
<!--## current-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_current']"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span
t-esc="account['percent_current']"
/>%
</div>
<!--## age_30_days-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_30_days']"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span
t-esc="account['percent_30_days']"
/>%
</div>
<!--## age_60_days-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_60_days']"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span
t-esc="account['percent_60_days']"
/>%
</div>
<!--## age_90_days-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_90_days']"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span
t-esc="account['percent_90_days']"
/>%
</div>
<!--## age_120_days-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_120_days']"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span
t-esc="account['percent_120_days']"
/>%
</div>
<!--## older-->
<div class="act_as_cell amount" style="width: 6.00%"><span t-esc="account['percent_older']"/>%
<div class="act_as_cell amount" style="width: 6.00%"><span
t-esc="account['percent_older']"
/>%
</div>
</t>
</div>
</div>
</template>
</odoo>

707
account_financial_report/report/templates/general_ledger.xml
File diff suppressed because it is too large
View File

572
account_financial_report/report/templates/journal_ledger.xml

@ -1,73 +1,87 @@
<?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>
<template id="journal_ledger">
<template id="journal_ledger">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
<t t-call="account_financial_report.report_journal_ledger_base"/>
<t t-call="account_financial_report.report_journal_ledger_base" />
</t>
</t>
</t>
</template>
<template id="report_journal_ledger_base">
<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"/>
<t t-set="display_currency" t-value="foreign_currency" />
<t t-set="display_account_name" t-value="with_account_name" />
<t t-set="title">Journal Ledger - <t t-raw="company_name" /> - <t
t-raw="currency_name"
/></t>
<t t-set="company_name" t-value="Company_Name" />
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
<h4
class="mt0"
t-esc="title or 'Odoo Report'"
style="text-align: center;"
/>
</div>
<t t-if="group_option == 'none'">
<div class="page_break">
<t t-call="account_financial_report.report_journal_all"/>
<br/>
<t t-call="account_financial_report.report_journal_all_taxes"/>
<t t-call="account_financial_report.report_journal_all" />
<br />
<t t-call="account_financial_report.report_journal_all_taxes" />
</div>
</t>
<t t-if="group_option == 'journal'">
<t t-foreach="Journal_Ledgers" t-as="journal">
<div class="page_break">
<t t-call="account_financial_report.report_journal_ledger_journal"/>
<br/>
<t t-call="account_financial_report.report_journal_ledger_journal_taxes"/>
<br/>
<t
t-call="account_financial_report.report_journal_ledger_journal"
/>
<br />
<t
t-call="account_financial_report.report_journal_ledger_journal_taxes"
/>
<br />
</div>
</t>
</t>
</div>
</template>
<template id="account_financial_report.report_journal_all">
<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%;">
<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="Moves" t-as="move">
<t t-call="account_financial_report.report_journal_move"/>
<t t-call="account_financial_report.report_journal_move" />
</t>
</div>
</template>
<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%;">
<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
<span t-esc="journal['name']" /> (<span
t-esc="journal['currency_name']"
/>) - <span t-esc="date_from" t-options="{'widget': 'date'}" /> to <span
t-esc="date_to"
t-options="{'widget': 'date'}"
/> - <span t-esc="move_target" /> Moves
</div>
<div class="act_as_table data_table" style="width: 100%;">
<t t-call="account_financial_report.report_journal_ledger_journal_table_header"/>
<t t-call="account_financial_report.report_journal_ledger_journal_first_line"/>
<t
t-call="account_financial_report.report_journal_ledger_journal_table_header"
/>
<t
t-call="account_financial_report.report_journal_ledger_journal_first_line"
/>
<t t-foreach="journal['report_moves']" t-as="move">
<t t-call="account_financial_report.report_journal_move"/>
<t t-call="account_financial_report.report_journal_move" />
</t>
</div>
</template>
<template id="account_financial_report.report_journal_ledger_journal_table_header">
<t t-if="not display_account_name">
<t t-set="account_column_style">
@ -85,395 +99,393 @@
width: 23.24%;
</t>
</t>
<div class="act_as_thead">
<div class="act_as_row labels">
<div class="act_as_cell first_column"
name="entry"
style="width: 7.57%;">
<div
class="act_as_cell first_column"
name="entry"
style="width: 7.57%;"
>
Entry
</div>
<div class="act_as_cell"
name="date"
style="width: 5.41%;">
<div class="act_as_cell" name="date" style="width: 5.41%;">
Date
</div>
<div class="act_as_cell"
name="account" t-att-style="account_column_style">
<div
class="act_as_cell"
name="account"
t-att-style="account_column_style"
>
Account
</div>
<div class="act_as_cell"
name="partner"
style="width: 15.14%;">
<div class="act_as_cell" name="partner" style="width: 15.14%;">
Partner
</div>
<div class="act_as_cell"
name="label" t-att-style="label_column_style">
<div class="act_as_cell" name="label" t-att-style="label_column_style">
Ref - Label
</div>
<div class="act_as_cell"
name="taxes"
style="width: 7.57%;">
<div class="act_as_cell" name="taxes" style="width: 7.57%;">
Taxes
</div>
<div class="act_as_cell"
name="debit"
style="width: 8.65%;">
<div class="act_as_cell" name="debit" style="width: 8.65%;">
Debit
</div>
<div class="act_as_cell"
name="credit"
style="width: 8.65%;">
<div class="act_as_cell" name="credit" style="width: 8.65%;">
Credit
</div>
<t t-if="display_currency">
<div class="act_as_cell"
name="currency_name"
style="width: 2.16%;">
<div class="act_as_cell" name="currency_name" style="width: 2.16%;">
Cur.
</div>
<div class="act_as_cell"
name="amount_currency"
style="width: 6.49%;">
<div
class="act_as_cell"
name="amount_currency"
style="width: 6.49%;"
>
Amount Cur.
</div>
</t>
</div>
</div>
</template>
<template id="account_financial_report.report_journal_ledger_journal_first_line">
<div class="act_as_row lines">
<div class="act_as_cell"
name="entry"/>
<div class="act_as_cell"
name="date"/>
<div class="act_as_cell"
name="account"/>
<div class="act_as_cell"
name="partner"/>
<div class="act_as_cell"
name="label"/>
<div class="act_as_cell"
name="taxes"/>
<div class="act_as_cell amount"
name="debit">
<b><span t-esc="journal['debit']" t-options="{'widget': 'float', 'precision': 2}"/></b>
<div class="act_as_cell" name="entry" />
<div class="act_as_cell" name="date" />
<div class="act_as_cell" name="account" />
<div class="act_as_cell" name="partner" />
<div class="act_as_cell" name="label" />
<div class="act_as_cell" name="taxes" />
<div class="act_as_cell amount" name="debit">
<b>
<span
t-esc="journal['debit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</b>
</div>
<div class="act_as_cell amount"
name="credit">
<b><span t-esc="journal['credit']" t-options="{'widget': 'float', 'precision': 2}"/></b>
<div class="act_as_cell amount" name="credit">
<b>
<span
t-esc="journal['credit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</b>
</div>
<t t-if="display_currency">
<div class="act_as_cell"
name="currency_name">
<div class="act_as_cell" name="currency_name">
</div>
<div class="act_as_cell amount"
name="amount_currency">
<div class="act_as_cell amount" name="amount_currency">
</div>
</t>
</div>
<div style="width: 100%"/>
<div style="width: 100%" />
</template>
<template id="account_financial_report.report_journal_move">
<t t-set="display_move_info" t-value="True"/>
<t t-set="last_partner" t-eval="None"/>
<t t-set="display_partner" t-eval="True"/>
<t t-set="display_move_info" t-value="True" />
<t t-set="last_partner" t-eval="None" />
<t t-set="display_partner" t-eval="True" />
<t t-foreach="move['report_move_lines']" t-as="move_line">
<div class="act_as_row lines">
<t t-set="current_partner" t-value="o._get_partner_name(move_line['partner_id'], partner_ids_data)"/>
<t t-set="display_partner" t-value="current_partner != last_partner"/>
<t t-call="account_financial_report.report_journal_move_line"/>
<t t-set="last_partner" t-value="current_partner"/>
<t t-set="display_move_info" t-value="False"/>
<t
t-set="current_partner"
t-value="o._get_partner_name(move_line['partner_id'], partner_ids_data)"
/>
<t t-set="display_partner" t-value="current_partner != last_partner" />
<t t-call="account_financial_report.report_journal_move_line" />
<t t-set="last_partner" t-value="current_partner" />
<t t-set="display_move_info" t-value="False" />
</div>
</t>
</template>
<template id="account_financial_report.report_journal_move_line">
<div class="act_as_cell left"
name="entry">
<t t-set="res_model" t-value="'account.move'"/>
<div class="act_as_cell left" name="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
t-att-data-active-id="move_line['move_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;"
>
<t
t-esc="o._get_atr_from_dict(move_line['move_id'], move_ids_data, 'entry')"
/>
</a>
</span>
</div>
<div class="act_as_cell left"
name="date">
<span t-if="display_move_info" t-esc="move_line['date']" t-options="{'widget': 'date'}"/>
<div class="act_as_cell left" name="date">
<span
t-if="display_move_info"
t-esc="move_line['date']"
t-options="{'widget': 'date'}"
/>
</div>
<div class="act_as_cell left"
name="account">
<span t-esc="o._get_atr_from_dict(move_line['account_id'], account_ids_data, 'code')"/>
<div class="act_as_cell left" name="account">
<span
t-esc="o._get_atr_from_dict(move_line['account_id'], account_ids_data, 'code')"
/>
<span t-if="display_account_name">
- <span t-esc="o._get_atr_from_dict(move_line['account_id'], account_ids_data, 'name')"/>
- <span
t-esc="o._get_atr_from_dict(move_line['account_id'], account_ids_data, 'name')"
/>
</span>
</div>
<div class="act_as_cell left"
name="partner">
<span t-if="display_partner" t-esc="o._get_partner_name(move_line['partner_id'], partner_ids_data)"/>
<div class="act_as_cell left" name="partner">
<span
t-if="display_partner"
t-esc="o._get_partner_name(move_line['partner_id'], partner_ids_data)"
/>
</div>
<div class="act_as_cell left"
name="label">
<span t-if="move_line['label']" t-esc="move_line['label']"/>
<div class="act_as_cell left" name="label">
<span t-if="move_line['label']" t-esc="move_line['label']" />
<span t-if="not move_line['label']">/</span>
</div>
<div class="act_as_cell left"
name="taxes">
<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 class="act_as_cell left" name="taxes">
<t
t-set="tax_line_dat"
t-value="o._get_data_from_dict(move_line['tax_line_id'], tax_line_data)"
/>
<t
t-set="move_line_ids_taxes_dat"
t-value="o._get_data_from_dict(move_line['move_line_id'], move_line_ids_taxes_data)"
/>
<span
t-esc="o._get_ml_tax_description(move_line, tax_line_dat, move_line_ids_taxes_dat)"
/>
</div>
<div class="act_as_cell amount"
name="debit">
<div class="act_as_cell amount" name="debit">
<t t-if="move_line['debit']">
<span t-esc="move_line['debit']" t-options="{'widget': 'float', 'precision': 2}"/>
<span
t-esc="move_line['debit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</t>
</div>
<div class="act_as_cell amount"
name="credit">
<div class="act_as_cell amount" name="credit">
<t t-if="move_line['credit']">
<span t-esc="move_line['credit']" t-options="{'widget': 'float', 'precision': 2}"/>
<span
t-esc="move_line['credit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</t>
</div>
<t t-if="display_currency">
<div class="act_as_cell"
name="currency_name">
<div class="act_as_cell" name="currency_name">
<t t-if="move_line['currency_id']">
<span t-esc="currency_ids_data.get(move_line['currency_id'], '')"/>
<span t-esc="currency_ids_data.get(move_line['currency_id'], '')" />
</t>
</div>
<div class="act_as_cell amount"
name="amount_currency">
<t t-if="move_line['amount_currency']" t-options="{'widget': 'float', 'precision': 2}">
<span t-esc="move_line['amount_currency']" t-options="{'widget': 'float', 'precision': 2}"/>
<div class="act_as_cell amount" name="amount_currency">
<t
t-if="move_line['amount_currency']"
t-options="{'widget': 'float', 'precision': 2}"
>
<span
t-esc="move_line['amount_currency']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</t>
</div>
</t>
</template>
<template id="account_financial_report.report_journal_ledger_journal_taxes">
<b>Taxes summary</b>
<div class="act_as_table data_table" style="width: 100%;">
<div class="act_as_thead">
<div class="act_as_row labels">
<div class="act_as_cell first_column"
name="name"
style="width: 30.97%;">
<div
class="act_as_cell first_column"
name="name"
style="width: 30.97%;"
>
Name
</div>
<div class="act_as_cell"
name="description"
style="width: 13.27%;">
<div class="act_as_cell" name="description" style="width: 13.27%;">
Description
</div>
<div class="act_as_cell"
name="base_amount"
style="width: 27.88%;">
<div class="act_as_cell" name="base_amount" style="width: 27.88%;">
Base Amount
</div>
<div class="act_as_cell"
name="tax_amount"
style="width: 27.88%;">
<div class="act_as_cell" name="tax_amount" style="width: 27.88%;">
Tax Amount
</div>
</div>
</div>
</div>
<div class="act_as_table data_table" style="width: 100%;">
<div class="act_as_row labels">
<div class="act_as_cell first_column"
name="name"
style="width: 30.97%;"/>
<div class="act_as_cell"
name="description"
style="width: 13.27%;"/>
<div class="act_as_cell"
name="base_debit"
style="width: 9.29%;">
<div
class="act_as_cell first_column"
name="name"
style="width: 30.97%;"
/>
<div class="act_as_cell" name="description" style="width: 13.27%;" />
<div class="act_as_cell" name="base_debit" style="width: 9.29%;">
Debit
</div>
<div class="act_as_cell"
name="base_credit"
style="width: 9.29%;">
<div class="act_as_cell" name="base_credit" style="width: 9.29%;">
Credit
</div>
<div class="act_as_cell"
name="base_balance"
style="width: 9.29%;">
<div class="act_as_cell" name="base_balance" style="width: 9.29%;">
Balance
</div>
<div class="act_as_cell"
name="tax_debit"
style="width: 9.29%;">
<div class="act_as_cell" name="tax_debit" style="width: 9.29%;">
Debit
</div>
<div class="act_as_cell"
name="tax_credit"
style="width: 9.29%;">
<div class="act_as_cell" name="tax_credit" style="width: 9.29%;">
Credit
</div>
<div class="act_as_cell"
name="tax_balance"
style="width: 9.29%;">
<div class="act_as_cell" name="tax_balance" style="width: 9.29%;">
Balance
</div>
</div>
<t t-foreach="journal['tax_lines']" t-as="tax_line">
<div class="act_as_row lines">
<div class="act_as_cell left"
name="tax_name">
<span t-esc="tax_line['tax_name']"/>
</div>
<div class="act_as_cell left"
name="tax_code">
<span t-esc="tax_line['tax_code']"/>
</div>
<div class="act_as_cell amount"
name="base_debit">
<span t-esc="tax_line['base_debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="base_credit">
<span t-esc="tax_line['base_credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="base_balance">
<span t-esc="tax_line['base_balance']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_debit">
<span t-esc="tax_line['tax_debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_credit">
<span t-esc="tax_line['tax_credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_balance">
<span t-esc="tax_line['tax_balance']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
</div>
<div class="act_as_row lines">
<div class="act_as_cell left" name="tax_name">
<span t-esc="tax_line['tax_name']" />
</div>
<div class="act_as_cell left" name="tax_code">
<span t-esc="tax_line['tax_code']" />
</div>
<div class="act_as_cell amount" name="base_debit">
<span
t-esc="tax_line['base_debit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="base_credit">
<span
t-esc="tax_line['base_credit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="base_balance">
<span
t-esc="tax_line['base_balance']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="tax_debit">
<span
t-esc="tax_line['tax_debit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="tax_credit">
<span
t-esc="tax_line['tax_credit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="tax_balance">
<span
t-esc="tax_line['tax_balance']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
</div>
</t>
</div>
</template>
<template id="account_financial_report.report_journal_all_taxes">
<b>Taxes summary</b>
<div class="act_as_table data_table" style="width: 100%;">
<div class="act_as_thead">
<div class="act_as_row labels">
<div class="act_as_cell first_column"
name="name"
style="width: 30.97%;">
<div
class="act_as_cell first_column"
name="name"
style="width: 30.97%;"
>
Name
</div>
<div class="act_as_cell"
name="description"
style="width: 13.27%;">
<div class="act_as_cell" name="description" style="width: 13.27%;">
Description
</div>
<div class="act_as_cell"
name="base_amount"
style="width: 27.88%;">
<div class="act_as_cell" name="base_amount" style="width: 27.88%;">
Base Amount
</div>
<div class="act_as_cell"
name="tax_amount"
style="width: 27.88%;">
<div class="act_as_cell" name="tax_amount" style="width: 27.88%;">
Tax Amount
</div>
</div>
</div>
</div>
<div class="act_as_table data_table" style="width: 100%;">10
<div class="act_as_row labels">
<div class="act_as_cell first_column"
name="name"
style="width: 30.97%;"/>
<div class="act_as_cell"
name="description"
style="width: 13.27%;"/>
<div class="act_as_cell"
name="base_debit"
style="width: 9.29%;">
<div
class="act_as_cell first_column"
name="name"
style="width: 30.97%;"
/>
<div class="act_as_cell" name="description" style="width: 13.27%;" />
<div class="act_as_cell" name="base_debit" style="width: 9.29%;">
Debit
</div>
<div class="act_as_cell"
name="base_credit"
style="width: 9.29%;">
<div class="act_as_cell" name="base_credit" style="width: 9.29%;">
Credit
</div>
<div class="act_as_cell"
name="base_balance"
style="width: 9.29%;">
<div class="act_as_cell" name="base_balance" style="width: 9.29%;">
Balance
</div>
<div class="act_as_cell"
name="tax_debit"
style="width: 9.29%;">
<div class="act_as_cell" name="tax_debit" style="width: 9.29%;">
Debit
</div>
<div class="act_as_cell"
name="tax_credit"
style="width: 9.29%;">
<div class="act_as_cell" name="tax_credit" style="width: 9.29%;">
Credit
</div>
<div class="act_as_cell"
name="tax_balance"
style="width: 9.29%;">
<div class="act_as_cell" name="tax_balance" style="width: 9.29%;">
Balance
</div>
</div>
<t t-foreach="ReportTaxLines" t-as="tax_line">
<div class="act_as_row lines">
<div class="act_as_cell left"
name="tax_name">
<span t-esc="tax_line['tax_name']"/>
</div>
<div class="act_as_cell left"
name="tax_code">
<span t-esc="tax_line['tax_code']"/>
</div>
<div class="act_as_cell amount"
name="base_debit">
<span t-esc="tax_line['base_debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="base_credit">
<span t-esc="tax_line['base_credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="base_balance">
<span t-esc="tax_line['base_balance']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_debit">
<span t-esc="tax_line['tax_debit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_credit">
<span t-esc="tax_line['tax_credit']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
<div class="act_as_cell amount"
name="tax_balance">
<span t-esc="tax_line['tax_balance']" t-options="{'widget': 'float', 'precision': 2}"/>
</div>
</div>
<div class="act_as_row lines">
<div class="act_as_cell left" name="tax_name">
<span t-esc="tax_line['tax_name']" />
</div>
<div class="act_as_cell left" name="tax_code">
<span t-esc="tax_line['tax_code']" />
</div>
<div class="act_as_cell amount" name="base_debit">
<span
t-esc="tax_line['base_debit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="base_credit">
<span
t-esc="tax_line['base_credit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="base_balance">
<span
t-esc="tax_line['base_balance']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="tax_debit">
<span
t-esc="tax_line['tax_debit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="tax_credit">
<span
t-esc="tax_line['tax_credit']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
<div class="act_as_cell amount" name="tax_balance">
<span
t-esc="tax_line['tax_balance']"
t-options="{'widget': 'float', 'precision': 2}"
/>
</div>
</div>
</t>
</div>
</template>
</odoo>

24
account_financial_report/report/templates/layouts.xml

@ -1,26 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="account_financial_report.internal_layout">
<div class="article">
<link href="/account_financial_report/static/src/css/report.css" rel="stylesheet"/>
<t t-raw="0" />
<link
href="/account_financial_report/static/src/css/report.css"
rel="stylesheet"
/>
<t t-raw="0" />
</div>
<div class="footer">
<div class="row">
<div class="col-6 custom_footer">
<span t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"/>
<span
t-esc="context_timestamp(datetime.datetime.now()).strftime('%Y-%m-%d %H:%M')"
/>
</div>
<div class="col-6 text-right custom_footer">
<ul class="list-inline">
<li class="list-inline-item"><span class="page"/></li>
<li class="list-inline-item">
<span class="page" />
</li>
<li class="list-inline-item">/</li>
<li class="list-inline-item"><span class="topage"/></li>
<li class="list-inline-item">
<span class="topage" />
</li>
</ul>
</div>
</div>
</div>
</template>
</odoo>

181
account_financial_report/report/templates/open_items.xml

@ -1,71 +1,84 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="open_items">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
<t t-call="account_financial_report.report_open_items_base"/>
<t t-call="account_financial_report.report_open_items_base" />
</t>
</t>
</t>
</template>
<template id="account_financial_report.report_open_items_base">
<!-- Saved flag fields into variables, used to define columns display -->
<t t-set="foreign_currency" t-value="foreign_currency"/>
<t t-set="foreign_currency" t-value="foreign_currency" />
<!-- Defines global variables used by internal layout -->
<t t-set="title">Open Items - <t t-raw="company_name"/> - <t t-raw="currency_name"/></t>
<t t-set="company_name" t-value="Company_Name"/>
<t t-set="title">Open Items - <t t-raw="company_name" /> - <t
t-raw="currency_name"
/></t>
<t t-set="company_name" t-value="Company_Name" />
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
<h4
class="mt0"
t-esc="title or 'Odoo Report'"
style="text-align: center;"
/>
</div>
<!-- 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="Open_Items.keys()" t-as="account_id">
<div class="page_break">
<!-- Display account header -->
<div class="act_as_table list_table" style="margin-top: 10px;" />
<div class="account_title"
style="width: 100%;">
<span t-esc="accounts_data[account_id]['code']"/>
<div class="account_title" style="width: 100%;">
<span t-esc="accounts_data[account_id]['code']" />
-
<span t-esc="accounts_data[account_id]['name']"/>
<span t-esc="accounts_data[account_id]['name']" />
</div>
<!-- Display account partners -->
<t t-foreach="Open_Items[account_id]" t-as="partner_id" >
<t t-foreach="Open_Items[account_id]" t-as="partner_id">
<div class="page_break">
<!-- Display partner header -->
<div class="act_as_caption account_title">
<span t-esc="partners_data[partner_id]['name']"/>
<span t-esc="partners_data[partner_id]['name']" />
</div>
<!-- Display partner move lines -->
<t t-call="account_financial_report.report_open_items_lines"/>
<t
t-call="account_financial_report.report_open_items_lines"
/>
<!-- Display partner footer -->
<t t-call="account_financial_report.report_open_items_ending_cumul">
<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-call="account_financial_report.report_open_items_ending_cumul"
>
<t
t-set="account_or_partner_id"
t-value="partners_data[partner_id]"
/>
<t
t-set="currency_id"
t-value="accounts_data[account_id]['currency_name']"
/>
<t t-set="type" t-value='"partner_type"' />
</t>
</div>
</t>
<!-- Display account footer -->
<t t-call="account_financial_report.report_open_items_ending_cumul">
<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="account_or_partner_id"
t-value="accounts_data[account_id]"
/>
<t
t-set="currency_id"
t-value="accounts_data[account_id]['currency_name']"
/>
<t t-set="type" t-value='"account_type"' />
</t>
</div>
</t>
</div>
</template>
<template id="account_financial_report.report_open_items_filters">
<div class="act_as_table data_table" style="width: 100%;">
<div class="act_as_row labels">
@ -75,7 +88,7 @@
</div>
<div class="act_as_row">
<div class="act_as_cell">
<span t-esc="date_at"/>
<span t-esc="date_at" />
</div>
<div class="act_as_cell">
<t t-if="target_move == 'posted'">All posted entries</t>
@ -88,7 +101,6 @@
</div>
</div>
</template>
<template id="account_financial_report.report_open_items_lines">
<div class="act_as_table data_table" style="width: 100%;">
<!-- Display table headers for lines -->
@ -121,91 +133,104 @@
<!--## currency_name-->
<div class="act_as_cell" style="width: 2.25%;">Cur.</div>
<!--## amount_total_due_currency-->
<div class="act_as_cell amount" style="width: 6.57%;">Cur. Original</div>
<div
class="act_as_cell amount"
style="width: 6.57%;"
>Cur. Original</div>
<!--## amount_residual_currency-->
<div class="act_as_cell amount" style="width: 6.57%;">Cur. Residual</div>
<div
class="act_as_cell amount"
style="width: 6.57%;"
>Cur. Residual</div>
</t>
</div>
</div>
<!-- Display each lines -->
<t t-foreach="Open_Items[account_id][partner_id]" t-as="line" >
<t t-foreach="Open_Items[account_id][partner_id]" t-as="line">
<!-- # lines or centralized lines -->
<div class="act_as_row lines">
<!--## date-->
<div class="act_as_cell left">
<span t-raw="line['date']"/>
<span t-raw="line['date']" />
</div>
<!--## move-->
<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_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;">
<t t-esc="line['move_name']"/>
<a
t-att-data-active-id="line['move_id']"
t-att-data-res-model="res_model"
class="o_account_financial_reports_web_action"
style="color: black;"
>
<t t-esc="line['move_name']" />
</a>
</span>
</div>
<!--## journal-->
<div class="act_as_cell left">
<span t-esc="line['journal']"/>
<span t-esc="line['journal']" />
</div>
<!--## account code-->
<div class="act_as_cell left">
<span t-esc="line['account']"/>
<span t-esc="line['account']" />
</div>
<!--## partner-->
<div class="act_as_cell left">
<!-- <span t-if="line.get('partner_id', False)" t-esc="line['partner_id']"/>-->
<span t-esc="line['partner_name']"/>
<!-- <span t-if="line.get('partner_id', False)" t-esc="line['partner_id']"/>-->
<span t-esc="line['partner_name']" />
</div>
<!--## ref - label-->
<div class="act_as_cell left">
<span t-esc="line['ref']"/>
<span t-esc="line['ref']" />
</div>
<!--## date_due-->
<div class="act_as_cell left">
<span t-esc="line['date_maturity']"/>
<span t-esc="line['date_maturity']" />
</div>
<!--## amount_total_due-->
<div class="act_as_cell amount">
<span t-if="line.get('original', False)" t-esc="line['original']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-if="line.get('original', False)"
t-esc="line['original']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<!--## amount_residual-->
<div class="act_as_cell amount">
<span t-esc="line['amount_residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<span
t-esc="line['amount_residual']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</div>
<t t-if="foreign_currency">
<t t-if="line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell amount">
<span t-esc="line['currency_name']"/>
<span t-esc="line['currency_name']" />
</div>
<!--## amount_total_due_currency-->
<div class="act_as_cell amount">
<span t-esc="line['amount_currency']"/>
<span t-esc="line['amount_currency']" />
</div>
<!--## amount_residual_currency-->
<div class="act_as_cell amount">
<span t-esc="line['amount_residual_currency']"/>
<span t-esc="line['amount_residual_currency']" />
</div>
</t>
<t t-if="not line['currency_id']">
<!--## currency_name-->
<div class="act_as_cell"/>
<!--## currency_name-->
<div class="act_as_cell" />
<!--## amount_total_due_currency-->
<div class="act_as_cell"/>
<div class="act_as_cell" />
<!--## amount_residual_currency-->
<div class="act_as_cell"/>
<div class="act_as_cell" />
</t>
</t>
</div>
</t>
</div>
</template>
<template id="account_financial_report.report_open_items_ending_cumul">
<!-- Display ending balance line for account or partner -->
<div class="act_as_table list_table" style="width: 100%;">
@ -213,43 +238,49 @@
<!--## date-->
<t t-if='type == "account_type"'>
<div class="act_as_cell first_column" style="width: 36.34%;">
<span t-esc="accounts_data[account_id]['code']"/>
<span t-esc="accounts_data[account_id]['code']" />
-
<span t-esc="accounts_data[account_id]['name']"/>
<span t-esc="accounts_data[account_id]['name']" />
</div>
<div class="act_as_cell right" style="width: 28.66%;">Ending
balance</div>
</t>
<t t-if='type == "partner_type"'>
<div class="act_as_cell first_column"
style="width: 36.34%;"/>
<div class="act_as_cell right"
style="width: 28.66%;">Partner ending balance</div>
<div class="act_as_cell first_column" style="width: 36.34%;" />
<div
class="act_as_cell right"
style="width: 28.66%;"
>Partner ending balance</div>
</t>
<!--## date_due-->
<div class="act_as_cell" style="width: 6.47%;"/>
<div class="act_as_cell" style="width: 6.47%;" />
<!--## amount_total_due-->
<div class="act_as_cell amount" style="width: 6.57%;"/>
<div class="act_as_cell amount" style="width: 6.57%;" />
<!--## amount_currency-->
<div class="act_as_cell amount" style="width: 6.57%;">
<t t-if='type == "account_type"'>
<span t-esc="total_amount[account_id]['residual']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<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}"/>
<span
t-esc="total_amount[account_id][partner_id]['residual']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
</t>
</div>
<!--## amount_total_due_currency + amount_residual_currency -->
<t t-if="foreign_currency">
<!--## currency_name-->
<div class="act_as_cell"/>
<!--## amount_total_due_currency-->
<div class="act_as_cell"/>
<!--## amount_residual_currency-->
<div class="act_as_cell"/>
<!--## currency_name-->
<div class="act_as_cell" />
<!--## amount_total_due_currency-->
<div class="act_as_cell" />
<!--## amount_residual_currency-->
<div class="act_as_cell" />
</t>
</div>
</div>
</template>
</odoo>

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

218
account_financial_report/report/templates/vat_report.xml

@ -1,32 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="vat_report">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="account_financial_report.internal_layout">
<t t-call="account_financial_report.report_vat_report_base"/>
<t t-call="account_financial_report.report_vat_report_base" />
</t>
</t>
</t>
</template>
<template id="account_financial_report.report_vat_report_base">
<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"/>
<t t-set="title">VAT Report - <t t-raw="company_name" /> - <t
t-raw="currency_name"
/></t>
<t t-set="company_name" t-value="company_name" />
<div class="page">
<div class="row">
<h4 class="mt0" t-esc="title or 'Odoo Report'" style="text-align: center;"/>
<h4
class="mt0"
t-esc="title or 'Odoo Report'"
style="text-align: center;"
/>
</div>
<!-- Display filters -->
<t t-call="account_financial_report.report_vat_report_filters"/>
<div class="page_break"/>
<t t-call="account_financial_report.report_vat_report_filters" />
<div class="page_break" />
<div class="act_as_table data_table" style="width: 100%;">
<!-- Display table headers for lines -->
<div class="act_as_thead">
<div class="act_as_row labels">
<!--## code-->
<div class="act_as_cell first_column" style="width: 5%;">Code</div>
<div
class="act_as_cell first_column"
style="width: 5%;"
>Code</div>
<!--## name-->
<div class="act_as_cell" style="width: 65%;">Name</div>
<!--## net-->
@ -35,102 +42,126 @@
<div class="act_as_cell" style="width: 15%;">Tax</div>
</div>
</div>
<t t-foreach="vat_report" t-as="tag_or_group">
<div class="act_as_row lines" style="font-weight: bold;">
<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_or_group['code']"/>
<!-- </a>-->
<!-- </span>-->
<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_or_group['code']" />
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell left oe_tooltip_string" style="width: 65%;">
<!-- <span>-->
<!-- <a t-att-data-active-id="res_id"-->
<!-- t-att-data-res-model="res_model"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- t-att-style="style">-->
<t t-att-style="style" t-raw="tag_or_group['name']"/>
<!-- </a>-->
<!-- </span>-->
<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_or_group['name']" />
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell amount" style="width: 15%;">
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_ids', 'in', [tax.tax_id.id for tax in tag.tax_ids]),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to)]"/>-->
<!-- <span>-->
<!-- <a t-att-data-domain="domain"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- t-att-style="style">-->
<t t-att-style="style" t-raw="tag_or_group['net']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_ids', 'in', [tax.tax_id.id for tax in tag.tax_ids]),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to)]"/>-->
<!-- <span>-->
<!-- <a t-att-data-domain="domain"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- t-att-style="style">-->
<t
t-att-style="style"
t-raw="tag_or_group['net']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell amount" style="width: 15%;">
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_line_id', 'in', [tax.tax_id.id for tax in tag.tax_ids]),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <span>-->
<!-- <a t-att-data-domain="domain"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- t-att-style="style">-->
<t t-att-style="style" t-raw="tag_or_group['tax']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_line_id', 'in', [tax.tax_id.id for tax in tag.tax_ids]),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <span>-->
<!-- <a t-att-data-domain="domain"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- t-att-style="style">-->
<t
t-att-style="style"
t-raw="tag_or_group['tax']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
</div>
</div>
<t t-if="tax_detail">
<t t-foreach="tag_or_group['taxes']" t-as="tax">
<div class="act_as_row lines">
<div class="act_as_cell" style="width: 5%;"/>
<div class="act_as_cell left oe_tooltip_string" style="padding-left: 20px; width: 65%;">
<!-- <span>-->
<!-- <a t-att-data-active-id="tax.tax_id.id"-->
<!-- t-att-data-res-model="res_model"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- t-att-style="style">-->
<t t-att-style="style" t-raw="tax['name']"/>
<!-- </a>-->
<!-- </span>-->
<div class="act_as_cell" style="width: 5%;" />
<div
class="act_as_cell left oe_tooltip_string"
style="padding-left: 20px; width: 65%;"
>
<!-- <span>-->
<!-- <a t-att-data-active-id="tax.tax_id.id"-->
<!-- t-att-data-res-model="res_model"-->
<!-- class="o_account_financial_reports_web_action"-->
<!-- t-att-style="style">-->
<t t-att-style="style" t-raw="tax['name']" />
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell amount" style="width: 15%;">
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_ids', 'in', tax.tax_id.ids),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <span>-->
<!-- <a t-att-data-domain="domain"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- t-att-style="style">-->
<t t-att-style="style" t-raw="tax['net']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_ids', 'in', tax.tax_id.ids),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <span>-->
<!-- <a t-att-data-domain="domain"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- t-att-style="style">-->
<t
t-att-style="style"
t-raw="tax['net']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
</div>
<div class="act_as_cell amount" style="width: 15%;">
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_line_id', '=', tax.tax_id.id),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <span>-->
<!-- <a t-att-data-domain="domain"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- t-att-style="style">-->
<t t-att-style="style" t-raw="tax['tax']" t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"/>
<!-- </a>-->
<!-- </span>-->
<!-- <t t-set="domain"-->
<!-- t-value="[('tax_line_id', '=', tax.tax_id.id),-->
<!-- ('date', '&gt;=', o.date_from),-->
<!-- ('date', '&lt;=', o.date_to),-->
<!-- ('tax_exigible', '=', True)]"/>-->
<!-- <span>-->
<!-- <a t-att-data-domain="domain"-->
<!-- t-att-data-res-model="'account.move.line'"-->
<!-- class="o_account_financial_reports_web_action_multi"-->
<!-- t-att-style="style">-->
<t
t-att-style="style"
t-raw="tax['tax']"
t-options="{'widget': 'monetary', 'display_currency': res_company.currency_id}"
/>
<!-- </a>-->
<!-- </span>-->
</div>
</div>
</t>
@ -139,7 +170,6 @@
</div>
</div>
</template>
<template id="account_financial_report.report_vat_report_filters">
<div class="act_as_table data_table" style="width: 100%;">
<div class="act_as_row labels">
@ -149,13 +179,13 @@
</div>
<div class="act_as_row">
<div class="act_as_cell">
<span t-esc="date_from"/>
<span t-esc="date_from" />
</div>
<div class="act_as_cell">
<span t-esc="date_to"/>
<span t-esc="date_to" />
</div>
<div class="act_as_cell">
<span t-esc="based_on"/>
<span t-esc="based_on" />
</div>
</div>
</div>

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

342
account_financial_report/report/trial_balance_xlsx.py

@ -7,118 +7,163 @@ from odoo import _, models
class TrialBalanceXslx(models.AbstractModel):
_name = 'report.a_f_r.report_trial_balance_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
_name = "report.a_f_r.report_trial_balance_xlsx"
_inherit = "report.account_financial_report.abstract_report_xlsx"
def _get_report_name(self, report, data=False):
company_id = data.get('company_id', False)
report_name = _('Trial Balance')
company_id = data.get("company_id", False)
report_name = _("Trial Balance")
if company_id:
company = self.env['res.company'].browse(company_id)
suffix = ' - %s - %s' % (
company.name, company.currency_id.name)
company = self.env["res.company"].browse(company_id)
suffix = " - {} - {}".format(company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
if not report.show_partner_details:
res = {
0: {'header': _('Code'), 'field': 'code', 'width': 10},
1: {'header': _('Account'), 'field': 'name', 'width': 60},
2: {'header': _('Initial balance'),
'field': 'initial_balance',
'type': 'amount',
'width': 14},
3: {'header': _('Debit'),
'field': 'debit',
'type': 'amount',
'width': 14},
4: {'header': _('Credit'),
'field': 'credit',
'type': 'amount',
'width': 14},
5: {'header': _('Period balance'),
'field': 'period_balance',
'type': 'amount',
'width': 14},
6: {'header': _('Ending balance'),
'field': 'final_balance',
'type': 'amount',
'width': 14},
0: {"header": _("Code"), "field": "code", "width": 10},
1: {"header": _("Account"), "field": "name", "width": 60},
2: {
"header": _("Initial balance"),
"field": "initial_balance",
"type": "amount",
"width": 14,
},
3: {
"header": _("Debit"),
"field": "debit",
"type": "amount",
"width": 14,
},
4: {
"header": _("Credit"),
"field": "credit",
"type": "amount",
"width": 14,
},
5: {
"header": _("Period balance"),
"field": "period_balance",
"type": "amount",
"width": 14,
},
6: {
"header": _("Ending balance"),
"field": "final_balance",
"type": "amount",
"width": 14,
},
}
if report.foreign_currency:
foreign_currency = {
7: {'header': _('Cur.'),
'field': 'currency_id',
'field_currency_balance': 'currency_id',
'type': 'many2one', 'width': 7},
8: {'header': _('Initial balance'),
'field': 'initial_balance_foreign_currency',
'type': 'amount_currency',
'width': 14},
9: {'header': _('Ending balance'),
'field': 'final_balance_foreign_currency',
'type': 'amount_currency',
'width': 14},
7: {
"header": _("Cur."),
"field": "currency_id",
"field_currency_balance": "currency_id",
"type": "many2one",
"width": 7,
},
8: {
"header": _("Initial balance"),
"field": "initial_balance_foreign_currency",
"type": "amount_currency",
"width": 14,
},
9: {
"header": _("Ending balance"),
"field": "final_balance_foreign_currency",
"type": "amount_currency",
"width": 14,
},
}
res = {**res, **foreign_currency}
return res
else:
res = {
0: {'header': _('Partner'), 'field': 'name', 'width': 70},
1: {'header': _('Initial balance'),
'field': 'initial_balance',
'type': 'amount',
'width': 14},
2: {'header': _('Debit'),
'field': 'debit',
'type': 'amount',
'width': 14},
3: {'header': _('Credit'),
'field': 'credit',
'type': 'amount',
'width': 14},
4: {'header': _('Period balance'),
'field': 'balance',
'type': 'amount',
'width': 14},
5: {'header': _('Ending balance'),
'field': 'ending_balance',
'type': 'amount',
'width': 14},
0: {"header": _("Partner"), "field": "name", "width": 70},
1: {
"header": _("Initial balance"),
"field": "initial_balance",
"type": "amount",
"width": 14,
},
2: {
"header": _("Debit"),
"field": "debit",
"type": "amount",
"width": 14,
},
3: {
"header": _("Credit"),
"field": "credit",
"type": "amount",
"width": 14,
},
4: {
"header": _("Period balance"),
"field": "balance",
"type": "amount",
"width": 14,
},
5: {
"header": _("Ending balance"),
"field": "ending_balance",
"type": "amount",
"width": 14,
},
}
if report.foreign_currency:
foreign_currency = {
6: {'header': _('Cur.'),
'field': 'currency_id',
'field_currency_balance': 'currency_id',
'type': 'many2one', 'width': 7},
7: {'header': _('Initial balance'),
'field': 'initial_currency_balance',
'type': 'amount_currency',
'width': 14},
8: {'header': _('Ending balance'),
'field': 'ending_currency_balance',
'type': 'amount_currency',
'width': 14},
6: {
"header": _("Cur."),
"field": "currency_id",
"field_currency_balance": "currency_id",
"type": "many2one",
"width": 7,
},
7: {
"header": _("Initial balance"),
"field": "initial_currency_balance",
"type": "amount_currency",
"width": 14,
},
8: {
"header": _("Ending balance"),
"field": "ending_currency_balance",
"type": "amount_currency",
"width": 14,
},
}
res = {**res, **foreign_currency}
return res
def _get_report_filters(self, report):
return [
[_('Date range filter'),
_('From: %s To: %s') % (report.date_from, report.date_to)],
[_('Target moves filter'),
_('All posted entries') if report.target_move == 'all' else _(
'All entries')],
[_('Account at 0 filter'),
_('Hide') if report.hide_account_at_0 else _('Show')],
[_('Show foreign currency'),
_('Yes') if report.foreign_currency else _('No')],
[_('Limit hierarchy levels'),
_('Level %s' % report.show_hierarchy_level) if
report.limit_hierarchy_level else _('No limit')],
[
_("Date range filter"),
_("From: %s To: %s") % (report.date_from, report.date_to),
],
[
_("Target moves filter"),
_("All posted entries")
if report.target_move == "all"
else _("All entries"),
],
[
_("Account at 0 filter"),
_("Hide") if report.hide_account_at_0 else _("Show"),
],
[
_("Show foreign currency"),
_("Yes") if report.foreign_currency else _("No"),
],
[
_("Limit hierarchy levels"),
_("Level %s" % report.show_hierarchy_level)
if report.limit_hierarchy_level
else _("No limit"),
],
]
def _get_col_count_filter_name(self):
@ -129,17 +174,17 @@ class TrialBalanceXslx(models.AbstractModel):
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']
"report.account_financial_report.trial_balance"
]._get_report_values(report, data)
trial_balance = res_data["trial_balance"]
total_amount = res_data["total_amount"]
partners_data = res_data["partners_data"]
accounts_data = res_data["accounts_data"]
hierarchy_on = res_data["hierarchy_on"]
show_partner_details = res_data["show_partner_details"]
show_hierarchy_level = res_data["show_hierarchy_level"]
foreign_currency = res_data["foreign_currency"]
limit_hierarchy_level = res_data["limit_hierarchy_level"]
if not show_partner_details:
# Display array header for account lines
self.write_array_header()
@ -147,17 +192,17 @@ class TrialBalanceXslx(models.AbstractModel):
# For each account
if not show_partner_details:
for balance in trial_balance:
if hierarchy_on == 'relation':
if hierarchy_on == "relation":
if limit_hierarchy_level:
if show_hierarchy_level > balance['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':
elif hierarchy_on == "computed":
if balance["type"] == "account_type":
if limit_hierarchy_level:
if show_hierarchy_level > balance['level']:
if show_hierarchy_level > balance["level"]:
# Display account lines
self.write_line_from_dict(balance)
else:
@ -167,8 +212,11 @@ class TrialBalanceXslx(models.AbstractModel):
else:
for account_id in total_amount:
# Write account title
self.write_array_title(accounts_data[account_id]['code'] + '- '
+ accounts_data[account_id]['name'])
self.write_array_title(
accounts_data[account_id]["code"]
+ "- "
+ accounts_data[account_id]["name"]
)
# Display array header for partner lines
self.write_array_header()
@ -178,43 +226,51 @@ class TrialBalanceXslx(models.AbstractModel):
# Display partner lines
self.write_line_from_dict_order(
total_amount[account_id][partner_id],
partners_data[partner_id])
partners_data[partner_id],
)
# Display account footer line
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']
})
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'])
accounts_data[account_id].update(
{
"initial_currency_balance": total_amount[account_id][
"initial_currency_balance"
],
"ending_currency_balance": total_amount[account_id][
"ending_currency_balance"
],
}
)
self.write_account_footer(
accounts_data[account_id],
accounts_data[account_id]["code"]
+ "- "
+ accounts_data[account_id]["name"],
)
# Line break
self.row_pos += 2
def write_line_from_dict_order(self, total_amount, partner_data):
total_amount.update({'name': str(partner_data['name'])})
total_amount.update({"name": str(partner_data["name"])})
self.write_line_from_dict(total_amount)
def write_line(self, line_object, type_object):
"""Write a line on current line using all defined columns field name.
Columns are defined with `_get_report_columns` method.
"""
if type_object == 'partner':
if type_object == "partner":
line_object.currency_id = line_object.report_account_id.currency_id
elif type_object == 'account':
elif type_object == "account":
line_object.currency_id = line_object.currency_id
super(TrialBalanceXslx, self).write_line(line_object)
@ -222,27 +278,27 @@ class TrialBalanceXslx(models.AbstractModel):
"""Specific function to write account footer for Trial Balance"""
format_amt = self._get_currency_amt_header_format_dict(account)
for col_pos, column in self.columns.items():
if column['field'] == 'name':
if column["field"] == "name":
value = name_value
else:
value = account[column['field']]
cell_type = column.get('type', 'string')
if cell_type == 'string':
self.sheet.write_string(self.row_pos, col_pos, value or '',
self.format_header_left)
elif cell_type == 'amount':
self.sheet.write_number(self.row_pos, col_pos, float(value),
self.format_header_amount)
elif cell_type == 'many2one' and account['currency_id']:
value = account[column["field"]]
cell_type = column.get("type", "string")
if cell_type == "string":
self.sheet.write_string(
self.row_pos, col_pos, value.name or '',
self.format_header_right)
elif cell_type == 'amount_currency' and account['currency_id']:
self.row_pos, col_pos, value or "", self.format_header_left
)
elif cell_type == "amount":
self.sheet.write_number(
self.row_pos, col_pos, float(value),
format_amt)
self.row_pos, col_pos, float(value), self.format_header_amount
)
elif cell_type == "many2one" and account["currency_id"]:
self.sheet.write_string(
self.row_pos, col_pos, value.name or "", self.format_header_right
)
elif cell_type == "amount_currency" and account["currency_id"]:
self.sheet.write_number(self.row_pos, col_pos, float(value), format_amt)
else:
self.sheet.write_string(
self.row_pos, col_pos, '',
self.format_header_right)
self.row_pos, col_pos, "", self.format_header_right
)
self.row_pos += 1

205
account_financial_report/report/vat_report.py

@ -2,188 +2,189 @@
# Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, api
from odoo import api, models
class VATReport(models.AbstractModel):
_name = 'report.account_financial_report.vat_report'
_name = "report.account_financial_report.vat_report"
def _get_tax_data(self, tax_ids):
taxes = self.env['account.tax'].browse(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
tax_data.update(
{
tax.id: {
"id": tax.id,
"name": tax.name,
"tax_group_id": tax.tax_group_id.id,
"tags_ids": tax.tag_ids.ids,
}
}
})
)
return tax_data
@api.model
def _get_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)]
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,
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,
)
vat_data = {}
tax_ids = set()
for tax_move_line in tax_move_lines:
tax_ml_id = tax_move_line['id']
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])
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_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),
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']
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]["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}
)
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']
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']
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'] = []
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]["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 = self.env["account.account.tag"].browse(tags_ids)
tags_data = {}
for tag in tags:
tags_data.update({tag.id: {
'code': "",
'name': tag.name}
})
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']
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]["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}
)
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']
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']
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'] = []
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[tag_id]["taxes"].append(vat_report[tag_id][tax_id])
vat_report_list.append(vat_report[tag_id])
return vat_report_list
@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']
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':
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)
vat_report_data, tax_data, tax_detail
)
else:
vat_report = self._get_vat_report_tag_data(
vat_report_data, tax_data, tax_detail)
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,
"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,
}

45
account_financial_report/report/vat_report_xlsx.py

@ -5,39 +5,34 @@ from odoo import _, models
class VATReportXslx(models.AbstractModel):
_name = 'report.a_f_r.report_vat_report_xlsx'
_inherit = 'report.account_financial_report.abstract_report_xlsx'
_name = "report.a_f_r.report_vat_report_xlsx"
_inherit = "report.account_financial_report.abstract_report_xlsx"
def _get_report_name(self, report, data):
company_id = data.get('company_id', False)
report_name = _('Vat Report')
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)
company = self.env["res.company"].browse(company_id)
suffix = " - {} - {}".format(company.name, company.currency_id.name)
report_name = report_name + suffix
return report_name
def _get_report_columns(self, report):
return {
0: {'header': _('Code'), 'field': 'code', 'width': 5},
1: {'header': _('Name'), 'field': 'name', 'width': 100},
2: {'header': _('Net'),
'field': 'net',
'type': 'amount',
'width': 14},
3: {'header': _('Tax'),
'field': 'tax',
'type': 'amount',
'width': 14},
0: {"header": _("Code"), "field": "code", "width": 5},
1: {"header": _("Name"), "field": "name", "width": 100},
2: {"header": _("Net"), "field": "net", "type": "amount", "width": 14},
3: {"header": _("Tax"), "field": "tax", "type": "amount", "width": 14},
}
def _get_report_filters(self, report):
return [
[_('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')]
[_("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):
@ -48,10 +43,10 @@ class VATReportXslx(models.AbstractModel):
def _generate_report_content(self, workbook, report, data):
res_data = self.env[
'report.account_financial_report.vat_report'
"report.account_financial_report.vat_report"
]._get_report_values(report, data)
vat_report = res_data['vat_report']
tax_detail = res_data['tax_detail']
vat_report = res_data["vat_report"]
tax_detail = res_data["tax_detail"]
# For each tax_tag tax_group
self.write_array_header()
for tag_or_group in vat_report:
@ -60,5 +55,5 @@ class VATReportXslx(models.AbstractModel):
# For each tax if detail taxes
if tax_detail:
for tax in tag_or_group['taxes']:
for tax in tag_or_group["taxes"]:
self.write_line_from_dict(tax)

202
account_financial_report/reports.xml

@ -1,30 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- PDF/HMTL REPORTS -->
<!-- General Ledger -->
<report
id="action_print_report_general_ledger_qweb"
model="general.ledger.report.wizard"
string="General Ledger"
report_type="qweb-pdf"
menu="False"
name="account_financial_report.general_ledger"
file="account_financial_report.general_ledger"
/>
id="action_print_report_general_ledger_qweb"
model="general.ledger.report.wizard"
string="General Ledger"
report_type="qweb-pdf"
menu="False"
name="account_financial_report.general_ledger"
file="account_financial_report.general_ledger"
/>
<report
id="action_print_report_general_ledger_html"
model="general.ledger.report.wizard"
string="General Ledger"
report_type="qweb-html"
menu="False"
name="account_financial_report.general_ledger"
file="account_financial_report.general_ledger"
/>
id="action_print_report_general_ledger_html"
model="general.ledger.report.wizard"
string="General Ledger"
report_type="qweb-html"
menu="False"
name="account_financial_report.general_ledger"
file="account_financial_report.general_ledger"
/>
<!-- Journal Ledger -->
<report id="action_print_journal_ledger_wizard_qweb"
<report
id="action_print_journal_ledger_wizard_qweb"
model="journal.ledger.report.wizard"
report_type="qweb-pdf"
menu="False"
@ -32,7 +30,8 @@
name="account_financial_report.journal_ledger"
file="account_financial_report.journal_ledger"
/>
<report id="action_print_journal_ledger_wizard_html"
<report
id="action_print_journal_ledger_wizard_html"
model="journal.ledger.report.wizard"
report_type="qweb-html"
menu="False"
@ -40,92 +39,86 @@
name="account_financial_report.journal_ledger"
file="account_financial_report.journal_ledger"
/>
<!-- Trial Balance -->
<report
id="action_report_trial_balance_qweb"
model="trial.balance.report.wizard"
string="Trial Balance"
menu="False"
report_type="qweb-pdf"
name="account_financial_report.trial_balance"
file="account_financial_report.trial_balance"
/>
id="action_report_trial_balance_qweb"
model="trial.balance.report.wizard"
string="Trial Balance"
menu="False"
report_type="qweb-pdf"
name="account_financial_report.trial_balance"
file="account_financial_report.trial_balance"
/>
<report
id="action_report_trial_balance_html"
model="trial.balance.report.wizard"
string="Trial Balance"
menu="False"
report_type="qweb-html"
name="account_financial_report.trial_balance"
file="account_financial_report.trial_balance"
/>
id="action_report_trial_balance_html"
model="trial.balance.report.wizard"
string="Trial Balance"
menu="False"
report_type="qweb-html"
name="account_financial_report.trial_balance"
file="account_financial_report.trial_balance"
/>
<!-- Open Items -->
<report
id="action_print_report_open_items_qweb"
model="open.items.report.wizard"
string="Open Items"
menu="False"
report_type="qweb-pdf"
name="account_financial_report.open_items"
file="account_financial_report.open_items"
id="action_print_report_open_items_qweb"
model="open.items.report.wizard"
string="Open Items"
menu="False"
report_type="qweb-pdf"
name="account_financial_report.open_items"
file="account_financial_report.open_items"
/>
<report
id="action_print_report_open_items_html"
model="open.items.report.wizard"
string="Open Items"
menu="False"
report_type="qweb-html"
name="account_financial_report.open_items"
file="account_financial_report.open_items"
id="action_print_report_open_items_html"
model="open.items.report.wizard"
string="Open Items"
menu="False"
report_type="qweb-html"
name="account_financial_report.open_items"
file="account_financial_report.open_items"
/>
<!-- Aged Partner Balance -->
<report
id="action_print_report_aged_partner_balance_qweb"
model="aged.partner.balance.report.wizard"
string="Aged Partner Balance"
report_type="qweb-pdf"
menu="False"
name="account_financial_report.aged_partner_balance"
file="account_financial_report.aged_partner_balance"
id="action_print_report_aged_partner_balance_qweb"
model="aged.partner.balance.report.wizard"
string="Aged Partner Balance"
report_type="qweb-pdf"
menu="False"
name="account_financial_report.aged_partner_balance"
file="account_financial_report.aged_partner_balance"
/>
<report
id="action_print_report_aged_partner_balance_html"
model="aged.partner.balance.report.wizard"
string="Aged Partner Balance"
report_type="qweb-html"
menu="False"
name="account_financial_report.aged_partner_balance"
file="account_financial_report.aged_partner_balance"
id="action_print_report_aged_partner_balance_html"
model="aged.partner.balance.report.wizard"
string="Aged Partner Balance"
report_type="qweb-html"
menu="False"
name="account_financial_report.aged_partner_balance"
file="account_financial_report.aged_partner_balance"
/>
<!-- VAT Report -->
<report
id="action_print_report_vat_report_qweb"
model="vat.report.wizard"
string="VAT Report"
report_type="qweb-pdf"
menu="False"
name="account_financial_report.vat_report"
file="account_financial_report.vat_report"
id="action_print_report_vat_report_qweb"
model="vat.report.wizard"
string="VAT Report"
report_type="qweb-pdf"
menu="False"
name="account_financial_report.vat_report"
file="account_financial_report.vat_report"
/>
<report
id="action_print_report_vat_report_html"
model="vat.report.wizard"
string="VAT Report"
report_type="qweb-html"
menu="False"
name="account_financial_report.vat_report"
file="account_financial_report.vat_report"
<report
id="action_print_report_vat_report_html"
model="vat.report.wizard"
string="VAT Report"
report_type="qweb-html"
menu="False"
name="account_financial_report.vat_report"
file="account_financial_report.vat_report"
/>
<!-- PDF REPORTS : paperformat -->
<record id="report_qweb_paperformat" model="report.paperformat">
<field name="name">Account financial report qweb paperformat</field>
<field name="default" eval="True"/>
<field name="default" eval="True" />
<field name="format">custom</field>
<field name="page_height">297</field>
<field name="page_width">210</field>
@ -134,37 +127,32 @@
<field name="margin_bottom">8</field>
<field name="margin_left">5</field>
<field name="margin_right">5</field>
<field name="header_line" eval="False"/>
<field name="header_line" eval="False" />
<field name="header_spacing">10</field>
<field name="dpi">110</field>
</record>
<record id="action_print_report_general_ledger_qweb" model="ir.actions.report">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
<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 id="action_report_trial_balance_qweb" model="ir.actions.report">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
<field name="paperformat_id" ref="report_qweb_paperformat" />
</record>
<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 id="action_print_report_aged_partner_balance_qweb" model="ir.actions.report">
<field name="paperformat_id" ref="report_qweb_paperformat"/>
<record
id="action_print_report_aged_partner_balance_qweb"
model="ir.actions.report"
>
<field name="paperformat_id" ref="report_qweb_paperformat" />
</record>
<record id="action_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>
<!-- XLSX REPORTS -->
<record id="action_report_general_ledger_xlsx" model="ir.actions.report">
<field name="name">General Ledger XLSX</field>
<field name="model">general.ledger.report.wizard</field>
@ -173,7 +161,6 @@
<field name="report_type">xlsx</field>
<field name="report_file">report_general_ledger</field>
</record>
<record id="action_report_journal_ledger_xlsx" model="ir.actions.report">
<field name="name">Journal Ledger XLSX</field>
<field name="model">journal.ledger.report.wizard</field>
@ -182,7 +169,6 @@
<field name="report_type">xlsx</field>
<field name="report_file">report_journal_ledger</field>
</record>
<record id="action_report_trial_balance_xlsx" model="ir.actions.report">
<field name="name">Trial Balance XLSX</field>
<field name="model">trial.balance.report.wizard</field>
@ -191,7 +177,6 @@
<field name="report_type">xlsx</field>
<field name="report_file">report_trial_balance</field>
</record>
<record id="action_report_open_items_xlsx" model="ir.actions.report">
<field name="name">Open Items XLSX</field>
<field name="model">open.items.report.wizard</field>
@ -200,7 +185,6 @@
<field name="report_type">xlsx</field>
<field name="report_file">report_open_items</field>
</record>
<record id="action_report_aged_partner_balance_xlsx" model="ir.actions.report">
<field name="name">Aged Partner Balance XLSX</field>
<field name="model">aged.partner.balance.report.wizard</field>
@ -209,7 +193,6 @@
<field name="report_type">xlsx</field>
<field name="report_file">report_aged_partner_balance</field>
</record>
<record id="action_report_vat_report_xlsx" model="ir.actions.report">
<field name="name">VAT Report XLSX</field>
<field name="model">vat.report.wizard</field>
@ -218,5 +201,4 @@
<field name="report_type">xlsx</field>
<field name="report_file">report_vat_report</field>
</record>
</odoo>

74
account_financial_report/static/src/css/report.css

@ -2,7 +2,7 @@
display: table !important;
background-color: white;
}
.act_as_row {
.act_as_row {
display: table-row !important;
page-break-inside: avoid;
}
@ -16,67 +16,77 @@
.act_as_tbody {
display: table-row-group !important;
}
.list_table, .data_table, .totals_table{
.list_table,
.data_table,
.totals_table {
width: 100% !important;
}
.act_as_row.labels {
background-color:#F0F0F0 !important;
}
.list_table, .data_table, .totals_table, .list_table .act_as_row {
border-left:0px;
border-right:0px;
text-align:center;
font-size:10px;
padding-right:3px;
padding-left:3px;
padding-top:2px;
padding-bottom:2px;
border-collapse:collapse;
background-color: #f0f0f0 !important;
}
.list_table,
.data_table,
.totals_table,
.list_table .act_as_row {
border-left: 0px;
border-right: 0px;
text-align: center;
font-size: 10px;
padding-right: 3px;
padding-left: 3px;
padding-top: 2px;
padding-bottom: 2px;
border-collapse: collapse;
}
.totals_table {
font-weight: bold;
text-align: center;
}
.list_table .act_as_row.labels, .list_table .act_as_row.initial_balance, .list_table .act_as_row.lines {
border-color:grey !important;
border-bottom:1px solid lightGrey !important;
.list_table .act_as_row.labels,
.list_table .act_as_row.initial_balance,
.list_table .act_as_row.lines {
border-color: grey !important;
border-bottom: 1px solid lightGrey !important;
}
.data_table .act_as_cell{
.data_table .act_as_cell {
border: 1px solid lightGrey;
text-align: center;
}
.data_table .act_as_cell, .list_table .act_as_cell, .totals_table .act_as_cell {
.data_table .act_as_cell,
.list_table .act_as_cell,
.totals_table .act_as_cell {
word-wrap: break-word;
}
.data_table .act_as_row.labels, .totals_table .act_as_row.labels {
.data_table .act_as_row.labels,
.totals_table .act_as_row.labels {
font-weight: bold;
}
.initial_balance .act_as_cell {
font-style:italic;
font-style: italic;
}
.account_title {
font-size:11px;
font-weight:bold;
font-size: 11px;
font-weight: bold;
}
.account_title.labels {
background-color:#F0F0F0 !important;
background-color: #f0f0f0 !important;
}
.act_as_cell.amount {
word-wrap:normal;
text-align:right;
word-wrap: normal;
text-align: right;
}
.act_as_cell.left {
text-align:left;
text-align: left;
}
.act_as_cell.right {
text-align:right;
text-align: right;
}
.list_table .act_as_cell{
/* border-right:1px solid lightGrey; uncomment to active column lines */
.list_table .act_as_cell {
/* border-right:1px solid lightGrey; uncomment to active column lines */
}
.list_table .act_as_cell.first_column {
padding-left: 0px;
/* border-left:1px solid lightGrey; uncomment to active column lines */
/* border-left:1px solid lightGrey; uncomment to active column lines */
}
.overflow_ellipsis {
text-overflow: ellipsis;
@ -84,7 +94,7 @@
white-space: nowrap;
}
.custom_footer {
font-size:7px !important;
font-size: 7px !important;
}
.page_break {
page-break-inside: avoid;

77
account_financial_report/static/src/js/account_financial_report_backend.js

@ -1,21 +1,20 @@
odoo.define('account_financial_report.account_financial_report_backend', function (require) {
'use strict';
var core = require('web.core');
var Widget = require('web.Widget');
var ControlPanelMixin = require('web.ControlPanelMixin');
var ReportWidget = require(
'account_financial_report.account_financial_report_widget'
);
odoo.define("account_financial_report.account_financial_report_backend", function(
require
) {
"use strict";
var core = require("web.core");
var Widget = require("web.Widget");
var ControlPanelMixin = require("web.ControlPanelMixin");
var ReportWidget = require("account_financial_report.account_financial_report_widget");
var report_backend = Widget.extend(ControlPanelMixin, {
// Stores all the parameters of the action.
events: {
'click .o_account_financial_reports_print': 'print',
'click .o_account_financial_reports_export': 'export',
"click .o_account_financial_reports_print": "print",
"click .o_account_financial_reports_export": "export",
},
init: function (parent, action) {
init: function(parent, action) {
this.actionManager = parent;
this.given_context = {};
this.odoo_context = action.context;
@ -23,50 +22,49 @@ odoo.define('account_financial_report.account_financial_report_backend', functio
if (action.context.context) {
this.given_context = action.context.context;
}
this.given_context.active_id = action.context.active_id ||
action.params.active_id;
this.given_context.active_id =
action.context.active_id || action.params.active_id;
this.given_context.model = action.context.active_model || false;
this.given_context.ttype = action.context.ttype || false;
return this._super.apply(this, arguments);
},
willStart: function () {
willStart: function() {
return $.when(this.get_html());
},
set_html: function () {
set_html: function() {
var self = this;
var def = $.when();
if (!this.report_widget) {
this.report_widget = new ReportWidget(this, this.given_context);
def = this.report_widget.appendTo(this.$el);
}
def.then(function () {
def.then(function() {
self.report_widget.$el.html(self.html);
});
},
start: function () {
start: function() {
this.set_html();
return this._super();
},
// Fetches the html and is previous report.context if any,
// else create it
get_html: function () {
get_html: function() {
var self = this;
var defs = [];
return this._rpc({
model: this.given_context.model,
method: 'get_html',
method: "get_html",
args: [self.given_context],
context: self.odoo_context,
})
.then(function (result) {
self.html = result.html;
defs.push(self.update_cp());
return $.when.apply($, defs);
});
}).then(function(result) {
self.html = result.html;
defs.push(self.update_cp());
return $.when.apply($, defs);
});
},
// Updates the control panel and render the elements that have yet
// to be rendered
update_cp: function () {
update_cp: function() {
if (this.$buttons) {
var status = {
breadcrumbs: this.actionManager.get_breadcrumbs(),
@ -75,40 +73,37 @@ odoo.define('account_financial_report.account_financial_report_backend', functio
return this.update_control_panel(status);
}
},
do_show: function () {
do_show: function() {
this._super();
this.update_cp();
},
print: function () {
print: function() {
var self = this;
this._rpc({
model: this.given_context.model,
method: 'print_report',
args: [this.given_context.active_id, 'qweb-pdf'],
method: "print_report",
args: [this.given_context.active_id, "qweb-pdf"],
context: self.odoo_context,
}).then(function (result) {
}).then(function(result) {
self.do_action(result);
});
},
export: function () {
export: function() {
var self = this;
this._rpc({
model: this.given_context.model,
method: 'print_report',
args: [this.given_context.active_id, 'xlsx'],
method: "print_report",
args: [this.given_context.active_id, "xlsx"],
context: self.odoo_context,
}).then(function (result) {
}).then(function(result) {
self.do_action(result);
});
},
canBeRemoved: function () {
canBeRemoved: function() {
return $.when();
},
});
core.action_registry.add(
"account_financial_report_backend",
report_backend
);
core.action_registry.add("account_financial_report_backend", report_backend);
return report_backend;
});

96
account_financial_report/static/src/js/account_financial_report_widgets.js

@ -1,86 +1,88 @@
odoo.define('account_financial_report.account_financial_report_widget', function
(require) {
'use strict';
var Widget = require('web.Widget');
odoo.define("account_financial_report.account_financial_report_widget", function(
require
) {
"use strict";
var Widget = require("web.Widget");
var accountFinancialReportWidget = Widget.extend({
events: {
'click .o_account_financial_reports_web_action':
'boundLink',
'click .o_account_financial_reports_web_action_multi':
'boundLinkmulti',
'click .o_account_financial_reports_web_action_monetary':
'boundLinkMonetary',
'click .o_account_financial_reports_web_action_monetary_multi':
'boundLinkMonetarymulti',
"click .o_account_financial_reports_web_action": "boundLink",
"click .o_account_financial_reports_web_action_multi": "boundLinkmulti",
"click .o_account_financial_reports_web_action_monetary":
"boundLinkMonetary",
"click .o_account_financial_reports_web_action_monetary_multi":
"boundLinkMonetarymulti",
},
init: function () {
init: function() {
this._super.apply(this, arguments);
},
start: function () {
start: function() {
return this._super.apply(this, arguments);
},
boundLink: function (e) {
var res_model = $(e.target).data('res-model');
var res_id = $(e.target).data('active-id');
boundLink: function(e) {
var res_model = $(e.target).data("res-model");
var res_id = $(e.target).data("active-id");
return this.do_action({
type: 'ir.actions.act_window',
type: "ir.actions.act_window",
res_model: res_model,
res_id: res_id,
views: [[false, 'form']],
target: 'current',
views: [[false, "form"]],
target: "current",
});
},
boundLinkmulti: function (e) {
var res_model = $(e.target).data('res-model');
var domain = $(e.target).data('domain');
boundLinkmulti: function(e) {
var res_model = $(e.target).data("res-model");
var domain = $(e.target).data("domain");
if (!res_model) {
res_model = $(e.target.parentElement).data('res-model');
res_model = $(e.target.parentElement).data("res-model");
}
if (!domain) {
domain = $(e.target.parentElement).data('domain');
domain = $(e.target.parentElement).data("domain");
}
return this.do_action({
type: 'ir.actions.act_window',
name: this._toTitleCase(res_model.split('.').join(' ')),
type: "ir.actions.act_window",
name: this._toTitleCase(res_model.split(".").join(" ")),
res_model: res_model,
domain: domain,
views: [[false, "list"], [false, "form"]],
target: 'current',
views: [
[false, "list"],
[false, "form"],
],
target: "current",
});
},
boundLinkMonetary: function (e) {
var res_model = $(e.target.parentElement).data('res-model');
var res_id = $(e.target.parentElement).data('active-id');
boundLinkMonetary: function(e) {
var res_model = $(e.target.parentElement).data("res-model");
var res_id = $(e.target.parentElement).data("active-id");
return this.do_action({
type: 'ir.actions.act_window',
type: "ir.actions.act_window",
res_model: res_model,
res_id: res_id,
views: [[false, 'form']],
target: 'current',
views: [[false, "form"]],
target: "current",
});
},
boundLinkMonetarymulti: function (e) {
var res_model = $(e.target.parentElement).data('res-model');
var domain = $(e.target.parentElement).data('domain');
boundLinkMonetarymulti: function(e) {
var res_model = $(e.target.parentElement).data("res-model");
var domain = $(e.target.parentElement).data("domain");
return this.do_action({
type: 'ir.actions.act_window',
type: "ir.actions.act_window",
res_model: res_model,
domain: domain,
views: [[false, "list"], [false, "form"]],
target: 'current',
views: [
[false, "list"],
[false, "form"],
],
target: "current",
});
},
_toTitleCase: function (str) {
return str.replace(/\w\S*/g, function (txt) {
return txt.charAt(0).toUpperCase() +
txt.substr(1).toLowerCase();
_toTitleCase: function(str) {
return str.replace(/\w\S*/g, function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
});
},
});
return accountFinancialReportWidget;
});

1
account_financial_report/tests/__init__.py

@ -1,4 +1,3 @@
# © 2016 Julien Coux (Camptocamp)
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).-

635
account_financial_report/tests/test_general_ledger.py

@ -4,92 +4,113 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
import time
from datetime import date
from odoo import api, fields
from odoo.tests import common
from odoo import fields, api
from datetime import date
class TestGeneralLedgerReport(common.TransactionCase):
def setUp(self):
super(TestGeneralLedgerReport, self).setUp()
self.before_previous_fy_year = fields.Date.from_string('2014-05-05')
self.previous_fy_date_start = fields.Date.from_string('2015-01-01')
self.previous_fy_date_end = fields.Date.from_string('2015-12-31')
self.fy_date_start = fields.Date.from_string('2016-01-01')
self.fy_date_end = fields.Date.from_string('2016-12-31')
self.receivable_account = self.env['account.account'].search([
('user_type_id.name', '=', 'Receivable')
], limit=1)
self.income_account = self.env['account.account'].search([
('user_type_id.name', '=', 'Income')
], limit=1)
self.unaffected_account = self.env['account.account'].search([
(
'user_type_id',
'=',
self.env.ref('account.data_unaffected_earnings').id
)], limit=1)
self.partner = self.env.ref('base.res_partner_12')
self.before_previous_fy_year = fields.Date.from_string("2014-05-05")
self.previous_fy_date_start = fields.Date.from_string("2015-01-01")
self.previous_fy_date_end = fields.Date.from_string("2015-12-31")
self.fy_date_start = fields.Date.from_string("2016-01-01")
self.fy_date_end = fields.Date.from_string("2016-12-31")
self.receivable_account = self.env["account.account"].search(
[("user_type_id.name", "=", "Receivable")], limit=1
)
self.income_account = self.env["account.account"].search(
[("user_type_id.name", "=", "Income")], limit=1
)
self.unaffected_account = self.env["account.account"].search(
[
(
"user_type_id",
"=",
self.env.ref("account.data_unaffected_earnings").id,
)
],
limit=1,
)
self.partner = self.env.ref("base.res_partner_12")
def _add_move(
self,
date,
receivable_debit,
receivable_credit,
income_debit,
income_credit,
unaffected_debit=0,
unaffected_credit=0
self,
date,
receivable_debit,
receivable_credit,
income_debit,
income_credit,
unaffected_debit=0,
unaffected_credit=0,
):
move_name = 'expense accrual'
journal = self.env['account.journal'].search([], limit=1)
partner = self.env.ref('base.res_partner_12')
move_name = "expense accrual"
journal = self.env["account.journal"].search([], limit=1)
partner = self.env.ref("base.res_partner_12")
move_vals = {
'journal_id': journal.id,
'name': move_name,
'date': date,
'line_ids': [
(0, 0, {
'name': move_name,
'debit': receivable_debit,
'credit': receivable_credit,
'account_id': self.receivable_account.id,
'partner_id': partner.id}),
(0, 0, {
'name': move_name,
'debit': income_debit,
'credit': income_credit,
'account_id': self.income_account.id,
'partner_id': partner.id}),
(0, 0, {
'name': move_name,
'debit': unaffected_debit,
'credit': unaffected_credit,
'account_id': self.unaffected_account.id,
'partner_id': partner.id}),
]}
move = self.env['account.move'].create(move_vals)
"journal_id": journal.id,
"name": move_name,
"date": date,
"line_ids": [
(
0,
0,
{
"name": move_name,
"debit": receivable_debit,
"credit": receivable_credit,
"account_id": self.receivable_account.id,
"partner_id": partner.id,
},
),
(
0,
0,
{
"name": move_name,
"debit": income_debit,
"credit": income_credit,
"account_id": self.income_account.id,
"partner_id": partner.id,
},
),
(
0,
0,
{
"name": move_name,
"debit": unaffected_debit,
"credit": unaffected_credit,
"account_id": self.unaffected_account.id,
"partner_id": partner.id,
},
),
],
}
move = self.env["account.move"].create(move_vals)
move.post()
def _get_report_lines(self, with_partners=False):
centralize = True
if with_partners:
centralize = False
company = self.env.ref('base.main_company')
general_ledger = self.env['general.ledger.report.wizard'].create({
'date_from': self.fy_date_start,
'date_to': self.fy_date_end,
'target_move': 'posted',
'hide_account_at_0': False,
'company_id': company.id,
'fy_start_date': self.fy_date_start,
'centralize': centralize,
})
company = self.env.ref("base.main_company")
general_ledger = self.env["general.ledger.report.wizard"].create(
{
"date_from": self.fy_date_start,
"date_to": self.fy_date_end,
"target_move": "posted",
"hide_account_at_0": False,
"company_id": company.id,
"fy_start_date": self.fy_date_start,
"centralize": centralize,
}
)
data = general_ledger._prepare_report_general_ledger()
res_data = self.env[
'report.account_financial_report.general_ledger'
"report.account_financial_report.general_ledger"
]._get_report_values(general_ledger, data)
return res_data
@ -97,7 +118,7 @@ class TestGeneralLedgerReport(common.TransactionCase):
def check_account_in_report(self, account_id, general_ledger):
account_in_report = False
for account in general_ledger:
if account['id'] == account_id:
if account["id"] == account_id:
account_in_report = True
break
return account_in_report
@ -106,9 +127,9 @@ class TestGeneralLedgerReport(common.TransactionCase):
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:
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
@ -116,49 +137,49 @@ class TestGeneralLedgerReport(common.TransactionCase):
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']
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):
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']
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']
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):
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']
if account["id"] == account_id and account["partners"]:
for partner in account["list_partner"]:
if partner["id"] == partner_id:
final_balance = partner["fin_bal"]
return final_balance
def test_01_account_balance(self):
# Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_receivable_account = self.check_account_in_report(
self.receivable_account.id, general_ledger)
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.income_account.id, general_ledger
)
self.assertFalse(check_income_account)
# Add a move at the previous day of the first day of fiscal year
@ -168,31 +189,35 @@ class TestGeneralLedgerReport(common.TransactionCase):
receivable_debit=1000,
receivable_credit=0,
income_debit=0,
income_credit=1000
income_credit=1000,
)
# Re Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_receivable_account = self.check_account_in_report(
self.receivable_account.id, general_ledger)
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.income_account.id, general_ledger
)
self.assertFalse(check_income_account)
# Check the initial and final balance
receivable_init_balance = self._get_initial_balance(
self.receivable_account.id, general_ledger)
self.receivable_account.id, general_ledger
)
receivable_fin_balance = self._get_final_balance(
self.receivable_account.id, general_ledger)
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)
self.assertEqual(receivable_init_balance["debit"], 1000)
self.assertEqual(receivable_init_balance["credit"], 0)
self.assertEqual(receivable_init_balance["balance"], 1000)
self.assertEqual(receivable_fin_balance["debit"], 1000)
self.assertEqual(receivable_fin_balance["credit"], 0)
self.assertEqual(receivable_fin_balance["balance"], 1000)
# Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -202,42 +227,48 @@ class TestGeneralLedgerReport(common.TransactionCase):
receivable_debit=0,
receivable_credit=1000,
income_debit=1000,
income_credit=0
income_credit=0,
)
# Re Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_receivable_account = self.check_account_in_report(
self.receivable_account.id, general_ledger)
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.income_account.id, general_ledger
)
self.assertTrue(check_income_account)
# Check the initial and final balance
receivable_init_balance = self._get_initial_balance(
self.receivable_account.id, general_ledger)
self.receivable_account.id, general_ledger
)
receivable_fin_balance = self._get_final_balance(
self.receivable_account.id, general_ledger)
self.receivable_account.id, general_ledger
)
income_init_balance = self._get_initial_balance(
self.income_account.id, general_ledger)
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)
self.income_account.id, general_ledger
)
self.assertEqual(receivable_init_balance["debit"], 1000)
self.assertEqual(receivable_init_balance["credit"], 0)
self.assertEqual(receivable_init_balance["balance"], 1000)
self.assertEqual(receivable_fin_balance["debit"], 1000)
self.assertEqual(receivable_fin_balance["credit"], 1000)
self.assertEqual(receivable_fin_balance["balance"], 0)
self.assertEqual(income_init_balance["debit"], 0)
self.assertEqual(income_init_balance["credit"], 0)
self.assertEqual(income_init_balance["balance"], 0)
self.assertEqual(income_fin_balance["debit"], 1000)
self.assertEqual(income_fin_balance["credit"], 0)
self.assertEqual(income_fin_balance["balance"], 1000)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
@ -246,49 +277,56 @@ class TestGeneralLedgerReport(common.TransactionCase):
receivable_debit=0,
receivable_credit=1000,
income_debit=1000,
income_credit=0
income_credit=0,
)
# Re Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_receivable_account = self.check_account_in_report(
self.receivable_account.id, general_ledger)
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.income_account.id, general_ledger
)
self.assertTrue(check_income_account)
# Check the initial and final balance
receivable_init_balance = self._get_initial_balance(
self.receivable_account.id, general_ledger)
self.receivable_account.id, general_ledger
)
receivable_fin_balance = self._get_final_balance(
self.receivable_account.id, general_ledger)
self.receivable_account.id, general_ledger
)
income_init_balance = self._get_initial_balance(
self.income_account.id, general_ledger)
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)
self.income_account.id, general_ledger
)
self.assertEqual(receivable_init_balance["debit"], 1000)
self.assertEqual(receivable_init_balance["credit"], 0)
self.assertEqual(receivable_init_balance["balance"], 1000)
self.assertEqual(receivable_fin_balance["debit"], 1000)
self.assertEqual(receivable_fin_balance["credit"], 2000)
self.assertEqual(receivable_fin_balance["balance"], -1000)
self.assertEqual(income_init_balance["debit"], 0)
self.assertEqual(income_init_balance["credit"], 0)
self.assertEqual(income_init_balance["balance"], 0)
self.assertEqual(income_fin_balance["debit"], 2000)
self.assertEqual(income_fin_balance["credit"], 0)
self.assertEqual(income_fin_balance["balance"], 2000)
def test_02_partner_balance(self):
# Generate the general ledger line
res_data = self._get_report_lines(with_partners=True)
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_partner = self.check_partner_in_report(
self.receivable_account.id, self.partner.id, general_ledger)
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
@ -298,14 +336,15 @@ class TestGeneralLedgerReport(common.TransactionCase):
receivable_debit=1000,
receivable_credit=0,
income_debit=0,
income_credit=1000
income_credit=1000,
)
# Re Generate the general ledger line
res_data = self._get_report_lines(with_partners=True)
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_partner = self.check_partner_in_report(
self.receivable_account.id, self.partner.id, general_ledger)
self.receivable_account.id, self.partner.id, general_ledger
)
self.assertTrue(check_partner)
# Check the initial and final balance
@ -316,12 +355,12 @@ class TestGeneralLedgerReport(common.TransactionCase):
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)
self.assertEqual(partner_initial_balance["debit"], 1000)
self.assertEqual(partner_initial_balance["credit"], 0)
self.assertEqual(partner_initial_balance["balance"], 1000)
self.assertEqual(partner_final_balance["debit"], 1000)
self.assertEqual(partner_final_balance["credit"], 0)
self.assertEqual(partner_final_balance["balance"], 1000)
# Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -331,14 +370,15 @@ class TestGeneralLedgerReport(common.TransactionCase):
receivable_debit=0,
receivable_credit=1000,
income_debit=1000,
income_credit=0
income_credit=0,
)
# Re Generate the general ledger line
res_data = self._get_report_lines(with_partners=True)
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_partner = self.check_partner_in_report(
self.receivable_account.id, self.partner.id, general_ledger)
self.receivable_account.id, self.partner.id, general_ledger
)
self.assertTrue(check_partner)
# Check the initial and final balance
@ -349,12 +389,12 @@ class TestGeneralLedgerReport(common.TransactionCase):
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)
self.assertEqual(partner_initial_balance["debit"], 1000)
self.assertEqual(partner_initial_balance["credit"], 0)
self.assertEqual(partner_initial_balance["balance"], 1000)
self.assertEqual(partner_final_balance["debit"], 1000)
self.assertEqual(partner_final_balance["credit"], 1000)
self.assertEqual(partner_final_balance["balance"], 0)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
@ -363,14 +403,15 @@ class TestGeneralLedgerReport(common.TransactionCase):
receivable_debit=0,
receivable_credit=1000,
income_debit=1000,
income_credit=0
income_credit=0,
)
# Re Generate the general ledger line
res_data = self._get_report_lines(with_partners=True)
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_partner = self.check_partner_in_report(
self.receivable_account.id, self.partner.id, general_ledger)
self.receivable_account.id, self.partner.id, general_ledger
)
self.assertTrue(check_partner)
# Check the initial and final balance
@ -381,33 +422,36 @@ class TestGeneralLedgerReport(common.TransactionCase):
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)
self.assertEqual(partner_initial_balance["debit"], 1000)
self.assertEqual(partner_initial_balance["credit"], 0)
self.assertEqual(partner_initial_balance["balance"], 1000)
self.assertEqual(partner_final_balance["debit"], 1000)
self.assertEqual(partner_final_balance["credit"], 2000)
self.assertEqual(partner_final_balance["balance"], -1000)
def test_03_unaffected_account_balance(self):
# Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
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)
self.assertEqual(unaffected_init_balance["debit"], 0)
self.assertEqual(unaffected_init_balance["credit"], 0)
self.assertEqual(unaffected_init_balance["balance"], 0)
self.assertEqual(unaffected_fin_balance["debit"], 0)
self.assertEqual(unaffected_fin_balance["credit"], 0)
self.assertEqual(unaffected_fin_balance["balance"], 0)
# Add a move at the previous day of the first day of fiscal year
# to check the initial balance
@ -416,28 +460,31 @@ class TestGeneralLedgerReport(common.TransactionCase):
receivable_debit=1000,
receivable_credit=0,
income_debit=0,
income_credit=1000
income_credit=1000,
)
# Re Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
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)
self.assertEqual(unaffected_init_balance["debit"], 0)
self.assertEqual(unaffected_init_balance["credit"], 1000)
self.assertEqual(unaffected_init_balance["balance"], -1000)
self.assertEqual(unaffected_fin_balance["debit"], 0)
self.assertEqual(unaffected_fin_balance["credit"], 1000)
self.assertEqual(unaffected_fin_balance["balance"], -1000)
# Add reversale move of the initial move the first day of fiscal year
# to check the first day of fiscal year is not used
@ -449,28 +496,31 @@ class TestGeneralLedgerReport(common.TransactionCase):
income_debit=0,
income_credit=1000,
unaffected_debit=1000,
unaffected_credit=0
unaffected_credit=0,
)
# Re Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
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)
self.assertEqual(unaffected_init_balance["debit"], 0)
self.assertEqual(unaffected_init_balance["credit"], 1000)
self.assertEqual(unaffected_init_balance["balance"], -1000)
self.assertEqual(unaffected_fin_balance["debit"], 1000)
self.assertEqual(unaffected_fin_balance["credit"], 1000)
self.assertEqual(unaffected_fin_balance["balance"], 0)
# Add another move at the end day of fiscal year
# to check that it correctly used on report
@ -481,49 +531,55 @@ class TestGeneralLedgerReport(common.TransactionCase):
income_debit=0,
income_credit=0,
unaffected_debit=0,
unaffected_credit=3000
unaffected_credit=3000,
)
# Re Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
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)
self.assertEqual(unaffected_init_balance["debit"], 0)
self.assertEqual(unaffected_init_balance["credit"], 1000)
self.assertEqual(unaffected_init_balance["balance"], -1000)
self.assertEqual(unaffected_fin_balance["debit"], 1000)
self.assertEqual(unaffected_fin_balance["credit"], 4000)
self.assertEqual(unaffected_fin_balance["balance"], -3000)
def test_04_unaffected_account_balance_2_years(self):
# Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
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)
self.assertEqual(unaffected_init_balance["debit"], 0)
self.assertEqual(unaffected_init_balance["credit"], 0)
self.assertEqual(unaffected_init_balance["balance"], 0)
self.assertEqual(unaffected_fin_balance["debit"], 0)
self.assertEqual(unaffected_fin_balance["credit"], 0)
self.assertEqual(unaffected_fin_balance["balance"], 0)
# Add a move at any date 2 years before the balance
# (to create an historic)
@ -532,28 +588,31 @@ class TestGeneralLedgerReport(common.TransactionCase):
receivable_debit=0,
receivable_credit=1000,
income_debit=1000,
income_credit=0
income_credit=0,
)
# Re Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
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)
self.assertEqual(unaffected_init_balance["debit"], 1000)
self.assertEqual(unaffected_init_balance["credit"], 0)
self.assertEqual(unaffected_init_balance["balance"], 1000)
self.assertEqual(unaffected_fin_balance["debit"], 1000)
self.assertEqual(unaffected_fin_balance["credit"], 0)
self.assertEqual(unaffected_fin_balance["balance"], 1000)
# Affect the company's result last year
self._add_move(
@ -563,7 +622,7 @@ class TestGeneralLedgerReport(common.TransactionCase):
income_debit=0,
income_credit=0,
unaffected_debit=0,
unaffected_credit=1000
unaffected_credit=1000,
)
# Add another move last year to test the initial balance this year
@ -574,79 +633,75 @@ class TestGeneralLedgerReport(common.TransactionCase):
income_debit=500,
income_credit=0,
unaffected_debit=0,
unaffected_credit=0
unaffected_credit=0,
)
# Re Generate the general ledger line
res_data = self._get_report_lines()
general_ledger = res_data['general_ledger']
general_ledger = res_data["general_ledger"]
check_unaffected_account = self.check_account_in_report(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
self.assertTrue(check_unaffected_account)
# Check the initial and final balance
unaffected_init_balance = self._get_initial_balance(
self.unaffected_account.id, general_ledger)
self.unaffected_account.id, general_ledger
)
unaffected_fin_balance = self._get_final_balance(
self.unaffected_account.id, general_ledger)
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)
self.assertEqual(unaffected_init_balance["debit"], 1500)
self.assertEqual(unaffected_init_balance["credit"], 1000)
self.assertEqual(unaffected_init_balance["balance"], 500)
self.assertEqual(unaffected_fin_balance["debit"], 1500)
self.assertEqual(unaffected_fin_balance["credit"], 1000)
self.assertEqual(unaffected_fin_balance["balance"], 500)
def test_partner_filter(self):
partner_1 = self.env.ref('base.res_partner_1')
partner_2 = self.env.ref('base.res_partner_2')
partner_3 = self.env.ref('base.res_partner_3')
partner_4 = self.env.ref('base.res_partner_4')
partner_1.write({'is_company': False,
'parent_id': partner_2.id})
partner_3.write({'is_company': False})
partner_1 = self.env.ref("base.res_partner_1")
partner_2 = self.env.ref("base.res_partner_2")
partner_3 = self.env.ref("base.res_partner_3")
partner_4 = self.env.ref("base.res_partner_4")
partner_1.write({"is_company": False, "parent_id": partner_2.id})
partner_3.write({"is_company": False})
expected_list = [partner_2.id, partner_3.id, partner_4.id]
context = {
'active_ids': [
partner_1.id, partner_2.id, partner_3.id, partner_4.id
],
'active_model': 'res.partner'
}
"active_ids": [partner_1.id, partner_2.id, partner_3.id, partner_4.id],
"active_model": "res.partner",
}
wizard = self.env["general.ledger.report.wizard"].with_context(context)
self.assertEqual(wizard._default_partners(), expected_list)
def test_validate_date(self):
company_id = self.env.ref('base.main_company')
company_id.write({
'fiscalyear_last_day': 31,
'fiscalyear_last_month': 12,
})
user = self.env.ref('base.user_root').with_context(
company_id=company_id.id)
wizard = self.env["general.ledger.report.wizard"].with_context(
user=user.id
)
self.assertEqual(wizard._init_date_from(),
time.strftime('%Y') + '-01-01')
company_id = self.env.ref("base.main_company")
company_id.write(
{"fiscalyear_last_day": 31, "fiscalyear_last_month": 12,}
)
user = self.env.ref("base.user_root").with_context(company_id=company_id.id)
wizard = self.env["general.ledger.report.wizard"].with_context(user=user.id)
self.assertEqual(wizard._init_date_from(), time.strftime("%Y") + "-01-01")
def test_validate_date_range(self):
data_type = self.env['date.range.type'].create({
'name': 'Fiscal year',
'company_id': False,
'allow_overlap': False
})
dr = self.env['date.range'].create({
'name': 'FS2015',
'date_start': '2018-01-01',
'date_end': '2018-12-31',
'type_id': data_type.id,
})
wizard = self.env["general.ledger.report.wizard"].create({
'date_range_id': dr.id})
data_type = self.env["date.range.type"].create(
{"name": "Fiscal year", "company_id": False, "allow_overlap": False}
)
dr = self.env["date.range"].create(
{
"name": "FS2015",
"date_start": "2018-01-01",
"date_end": "2018-12-31",
"type_id": data_type.id,
}
)
wizard = self.env["general.ledger.report.wizard"].create(
{"date_range_id": dr.id}
)
wizard.onchange_date_range_id()
self.assertEqual(wizard.date_from, date(2018, 1, 1))
self.assertEqual(wizard.date_to, date(2018, 12, 31))

426
account_financial_report/tests/test_journal_ledger.py

@ -3,6 +3,7 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from datetime import datetime
from dateutil.relativedelta import relativedelta
from odoo.fields import Date
@ -10,193 +11,200 @@ from odoo.tests.common import TransactionCase
class TestJournalReport(TransactionCase):
def setUp(self):
super(TestJournalReport, self).setUp()
self.AccountObj = self.env['account.account']
self.InvoiceObj = self.env['account.invoice']
self.JournalObj = self.env['account.journal']
self.MoveObj = self.env['account.move']
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.AccountObj = self.env["account.account"]
self.InvoiceObj = self.env["account.invoice"]
self.JournalObj = self.env["account.journal"]
self.MoveObj = self.env["account.move"]
self.TaxObj = self.env["account.tax"]
self.JournalLedgerReportWizard = self.env["journal.ledger.report.wizard"]
self.JournalLedgerReport = self.env[
"report.account_financial_report.journal_ledger"
]
self.company = self.env.ref("base.main_company")
today = datetime.today()
last_year = today - relativedelta(years=1)
self.previous_fy_date_start = Date.to_string(
last_year.replace(month=1, day=1))
self.previous_fy_date_end = Date.to_string(
last_year.replace(month=12, day=31))
self.fy_date_start = Date.to_string(
today.replace(month=1, day=1))
self.fy_date_end = Date.to_string(
today.replace(month=12, day=31))
self.receivable_account = self.AccountObj.search([
('user_type_id.name', '=', 'Receivable')
], limit=1)
self.income_account = self.AccountObj.search([
('user_type_id.name', '=', 'Income')
], limit=1)
self.payable_account = self.AccountObj.search([
('user_type_id.name', '=', 'Payable')
], limit=1)
self.journal_sale = self.JournalObj.create({
'name': "Test journal sale",
'code': "TST-JRNL-S",
'type': 'sale',
'company_id': self.company.id,
})
self.journal_purchase = self.JournalObj.create({
'name': "Test journal purchase",
'code': "TST-JRNL-P",
'type': 'sale',
'company_id': self.company.id,
})
self.tax_15_s = self.TaxObj.create({
'sequence': 30,
'name': 'Tax 15.0% (Percentage of Price)',
'amount': 15.0,
'amount_type': 'percent',
'include_base_amount': False,
'type_tax_use': 'sale',
})
self.tax_20_s = self.TaxObj.create({
'sequence': 30,
'name': 'Tax 20.0% (Percentage of Price)',
'amount': 20.0,
'amount_type': 'percent',
'include_base_amount': False,
'type_tax_use': 'sale',
})
self.tax_15_p = self.TaxObj.create({
'sequence': 30,
'name': 'Tax 15.0% (Percentage of Price)',
'amount': 15.0,
'amount_type': 'percent',
'include_base_amount': False,
'type_tax_use': 'purchase',
})
self.tax_20_p = self.TaxObj.create({
'sequence': 30,
'name': 'Tax 20.0% (Percentage of Price)',
'amount': 20.0,
'amount_type': 'percent',
'include_base_amount': False,
'type_tax_use': 'purchase',
})
self.partner_2 = self.env.ref('base.res_partner_2')
self.previous_fy_date_start = Date.to_string(last_year.replace(month=1, day=1))
self.previous_fy_date_end = Date.to_string(last_year.replace(month=12, day=31))
self.fy_date_start = Date.to_string(today.replace(month=1, day=1))
self.fy_date_end = Date.to_string(today.replace(month=12, day=31))
self.receivable_account = self.AccountObj.search(
[("user_type_id.name", "=", "Receivable")], limit=1
)
self.income_account = self.AccountObj.search(
[("user_type_id.name", "=", "Income")], limit=1
)
self.payable_account = self.AccountObj.search(
[("user_type_id.name", "=", "Payable")], limit=1
)
self.journal_sale = self.JournalObj.create(
{
"name": "Test journal sale",
"code": "TST-JRNL-S",
"type": "sale",
"company_id": self.company.id,
}
)
self.journal_purchase = self.JournalObj.create(
{
"name": "Test journal purchase",
"code": "TST-JRNL-P",
"type": "sale",
"company_id": self.company.id,
}
)
self.tax_15_s = self.TaxObj.create(
{
"sequence": 30,
"name": "Tax 15.0% (Percentage of Price)",
"amount": 15.0,
"amount_type": "percent",
"include_base_amount": False,
"type_tax_use": "sale",
}
)
self.tax_20_s = self.TaxObj.create(
{
"sequence": 30,
"name": "Tax 20.0% (Percentage of Price)",
"amount": 20.0,
"amount_type": "percent",
"include_base_amount": False,
"type_tax_use": "sale",
}
)
self.tax_15_p = self.TaxObj.create(
{
"sequence": 30,
"name": "Tax 15.0% (Percentage of Price)",
"amount": 15.0,
"amount_type": "percent",
"include_base_amount": False,
"type_tax_use": "purchase",
}
)
self.tax_20_p = self.TaxObj.create(
{
"sequence": 30,
"name": "Tax 20.0% (Percentage of Price)",
"amount": 20.0,
"amount_type": "percent",
"include_base_amount": False,
"type_tax_use": "purchase",
}
)
self.partner_2 = self.env.ref("base.res_partner_2")
def _add_move(
self, date, journal,
receivable_debit, receivable_credit, income_debit, income_credit):
move_name = 'move name'
self,
date,
journal,
receivable_debit,
receivable_credit,
income_debit,
income_credit,
):
move_name = "move name"
move_vals = {
'journal_id': journal.id,
'date': date,
'line_ids': [
(0, 0, {
'name': move_name,
'debit': receivable_debit,
'credit': receivable_credit,
'account_id': self.receivable_account.id
}),
(0, 0, {
'name': move_name,
'debit': income_debit,
'credit': income_credit,
'account_id': self.income_account.id
}),
]
"journal_id": journal.id,
"date": date,
"line_ids": [
(
0,
0,
{
"name": move_name,
"debit": receivable_debit,
"credit": receivable_credit,
"account_id": self.receivable_account.id,
},
),
(
0,
0,
{
"name": move_name,
"debit": income_debit,
"credit": income_credit,
"account_id": self.income_account.id,
},
),
],
}
return self.MoveObj.create(move_vals)
def check_report_journal_debit_credit(
self, res_data, expected_debit, expected_credit):
self, res_data, expected_debit, expected_credit
):
self.assertEqual(
expected_debit,
sum([rec['debit'] for rec in res_data['Journal_Ledgers']])
expected_debit, sum([rec["debit"] for rec in res_data["Journal_Ledgers"]])
)
self.assertEqual(
expected_credit,
sum([rec['credit'] for rec in res_data['Journal_Ledgers']])
expected_credit, sum([rec["credit"] for rec in res_data["Journal_Ledgers"]])
)
def check_report_journal_debit_credit_taxes(
self, res_data,
expected_base_debit, expected_base_credit,
expected_tax_debit, expected_tax_credit):
for rec in res_data['Journal_Ledgers']:
self,
res_data,
expected_base_debit,
expected_base_credit,
expected_tax_debit,
expected_tax_credit,
):
for rec in res_data["Journal_Ledgers"]:
self.assertEqual(
expected_base_debit,
sum([
tax_line['base_debit']
for tax_line in rec['tax_lines']
])
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']
])
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']
])
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']
])
sum([tax_line["tax_credit"] for tax_line in rec["tax_lines"]]),
)
def test_01_test_total(self):
today_date = Date.today()
last_year_date = Date.to_string(
datetime.today() - relativedelta(years=1))
move1 = self._add_move(
today_date, self.journal_sale,
0, 100, 100, 0)
move2 = self._add_move(
last_year_date, self.journal_sale,
0, 100, 100, 0)
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start,
'date_to': self.fy_date_end,
'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)]
})
last_year_date = Date.to_string(datetime.today() - relativedelta(years=1))
move1 = self._add_move(today_date, self.journal_sale, 0, 100, 100, 0)
move2 = self._add_move(last_year_date, self.journal_sale, 0, 100, 100, 0)
wiz = self.JournalLedgerReportWizard.create(
{
"date_from": self.fy_date_start,
"date_to": self.fy_date_end,
"company_id": self.company.id,
"journal_ids": [(6, 0, self.journal_sale.ids)],
}
)
data = wiz._prepare_report_journal_ledger()
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 100, 100)
move3 = self._add_move(
today_date, self.journal_sale,
0, 100, 100, 0)
move3 = self._add_move(today_date, self.journal_sale, 0, 100, 100, 0)
res_data = self.JournalLedgerReport._get_report_values(wiz, data)
self.check_report_journal_debit_credit(res_data, 200, 200)
wiz.move_target = 'posted'
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)
@ -220,37 +228,47 @@ class TestJournalReport(TransactionCase):
def test_02_test_taxes_out_invoice(self):
invoice_values = {
'journal_id': self.journal_sale.id,
'partner_id': self.partner_2.id,
'type': 'out_invoice',
'invoice_line_ids': [
(0, 0, {
'quantity': 1.0,
'price_unit': 100,
'account_id': self.receivable_account.id,
'name': "Test",
'invoice_line_tax_ids': [(6, 0, [self.tax_15_s.id])],
}),
(0, 0, {
'quantity': 1.0,
'price_unit': 100,
'account_id': self.receivable_account.id,
'name': "Test",
'invoice_line_tax_ids': [(6, 0, [
self.tax_15_s.id, self.tax_20_s.id
])],
})
]
"journal_id": self.journal_sale.id,
"partner_id": self.partner_2.id,
"type": "out_invoice",
"invoice_line_ids": [
(
0,
0,
{
"quantity": 1.0,
"price_unit": 100,
"account_id": self.receivable_account.id,
"name": "Test",
"invoice_line_tax_ids": [(6, 0, [self.tax_15_s.id])],
},
),
(
0,
0,
{
"quantity": 1.0,
"price_unit": 100,
"account_id": self.receivable_account.id,
"name": "Test",
"invoice_line_tax_ids": [
(6, 0, [self.tax_15_s.id, self.tax_20_s.id])
],
},
),
],
}
invoice = self.InvoiceObj.create(invoice_values)
invoice.action_invoice_open()
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start,
'date_to': self.fy_date_end,
'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)]
})
wiz = self.JournalLedgerReportWizard.create(
{
"date_from": self.fy_date_start,
"date_to": self.fy_date_end,
"company_id": self.company.id,
"journal_ids": [(6, 0, self.journal_sale.ids)],
}
)
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)
@ -258,37 +276,47 @@ class TestJournalReport(TransactionCase):
def test_03_test_taxes_in_invoice(self):
invoice_values = {
'journal_id': self.journal_sale.id,
'partner_id': self.partner_2.id,
'type': 'in_invoice',
'invoice_line_ids': [
(0, 0, {
'quantity': 1.0,
'price_unit': 100,
'account_id': self.payable_account.id,
'name': "Test",
'invoice_line_tax_ids': [(6, 0, [self.tax_15_p.id])],
}),
(0, 0, {
'quantity': 1.0,
'price_unit': 100,
'account_id': self.payable_account.id,
'name': "Test",
'invoice_line_tax_ids': [(6, 0, [
self.tax_15_p.id, self.tax_20_p.id
])],
})
]
"journal_id": self.journal_sale.id,
"partner_id": self.partner_2.id,
"type": "in_invoice",
"invoice_line_ids": [
(
0,
0,
{
"quantity": 1.0,
"price_unit": 100,
"account_id": self.payable_account.id,
"name": "Test",
"invoice_line_tax_ids": [(6, 0, [self.tax_15_p.id])],
},
),
(
0,
0,
{
"quantity": 1.0,
"price_unit": 100,
"account_id": self.payable_account.id,
"name": "Test",
"invoice_line_tax_ids": [
(6, 0, [self.tax_15_p.id, self.tax_20_p.id])
],
},
),
],
}
invoice = self.InvoiceObj.create(invoice_values)
invoice.action_invoice_open()
wiz = self.JournalLedgerReportWizard.create({
'date_from': self.fy_date_start,
'date_to': self.fy_date_end,
'company_id': self.company.id,
'journal_ids': [(6, 0, self.journal_sale.ids)]
})
wiz = self.JournalLedgerReportWizard.create(
{
"date_from": self.fy_date_start,
"date_to": self.fy_date_end,
"company_id": self.company.id,
"journal_ids": [(6, 0, self.journal_sale.ids)],
}
)
data = wiz._prepare_report_journal_ledger()
res_data = self.JournalLedgerReport._get_report_values(wiz, data)

22
account_financial_report/tests/test_open_items.py

@ -6,23 +6,19 @@ from odoo.tests.common import TransactionCase
class TestOpenItems(TransactionCase):
def test_partner_filter(self):
partner_1 = self.env.ref('base.res_partner_1')
partner_2 = self.env.ref('base.res_partner_2')
partner_3 = self.env.ref('base.res_partner_3')
partner_4 = self.env.ref('base.res_partner_4')
partner_1.write({'is_company': False,
'parent_id': partner_2.id})
partner_3.write({'is_company': False})
partner_1 = self.env.ref("base.res_partner_1")
partner_2 = self.env.ref("base.res_partner_2")
partner_3 = self.env.ref("base.res_partner_3")
partner_4 = self.env.ref("base.res_partner_4")
partner_1.write({"is_company": False, "parent_id": partner_2.id})
partner_3.write({"is_company": False})
expected_list = [partner_2.id, partner_3.id, partner_4.id]
context = {
'active_ids': [
partner_1.id, partner_2.id, partner_3.id, partner_4.id
],
'active_model': 'res.partner'
}
"active_ids": [partner_1.id, partner_2.id, partner_3.id, partner_4.id],
"active_model": "res.partner",
}
wizard = self.env["open.items.report.wizard"].with_context(context)
self.assertEqual(wizard._default_partners(), expected_list)

917
account_financial_report/tests/test_trial_balance.py
File diff suppressed because it is too large
View File

398
account_financial_report/tests/test_vat_report.py

@ -4,145 +4,166 @@
import time
from datetime import date
from odoo.tests import common
class TestVATReport(common.TransactionCase):
def setUp(self):
super(TestVATReport, self).setUp()
self.date_from = time.strftime('%Y-%m-01')
self.date_to = time.strftime('%Y-%m-28')
self.company = self.env.ref('base.main_company')
self.receivable_account = self.env['account.account'].search([
('company_id', '=', self.company.id),
('user_type_id.name', '=', 'Receivable')
], limit=1)
self.income_account = self.env['account.account'].search([
('company_id', '=', self.company.id),
('user_type_id.name', '=', 'Income')
], limit=1)
self.tax_account = self.env['account.account'].search([
('company_id', '=', self.company.id),
('user_type_id',
'=',
self.env.ref(
'account.data_account_type_non_current_liabilities').id)
], limit=1)
self.bank_journal = self.env['account.journal'].search([
('type', '=', 'bank'), ('company_id', '=', self.company.id)
], limit=1)
self.tax_tag_01 = self.env['account.account.tag'].create({
'name': 'Tag 01',
'applicability': 'taxes'
})
self.tax_tag_02 = self.env['account.account.tag'].create({
'name': 'Tag 02',
'applicability': 'taxes'
})
self.tax_tag_03 = self.env['account.account.tag'].create({
'name': 'Tag 03',
'applicability': 'taxes'
})
self.tax_group_10 = self.env['account.tax.group'].create({
'name': 'Tax 10%',
'sequence': 1
})
self.tax_group_20 = self.env['account.tax.group'].create({
'name': 'Tax 20%',
'sequence': 2
})
self.tax_10 = self.env['account.tax'].create({
'name': 'Tax 10.0%',
'amount': 10.0,
'amount_type': 'percent',
'type_tax_use': 'sale',
'account_id': self.tax_account.id,
'company_id': self.company.id,
'refund_account_id': self.tax_account.id,
'tax_group_id': self.tax_group_10.id,
'tag_ids': [(6, 0, [self.tax_tag_01.id, self.tax_tag_02.id])]
})
self.tax_20 = self.env['account.tax'].create({
'sequence': 30,
'name': 'Tax 20.0%',
'amount': 20.0,
'amount_type': 'percent',
'type_tax_use': 'sale',
'tax_exigibility': 'on_payment',
'account_id': self.tax_account.id,
'company_id': self.company.id,
'refund_account_id': self.tax_account.id,
'cash_basis_account_id': self.tax_account.id,
'tax_group_id': self.tax_group_20.id,
'tag_ids': [(6, 0, [self.tax_tag_02.id, self.tax_tag_03.id])]
})
self.date_from = time.strftime("%Y-%m-01")
self.date_to = time.strftime("%Y-%m-28")
self.company = self.env.ref("base.main_company")
self.receivable_account = self.env["account.account"].search(
[
("company_id", "=", self.company.id),
("user_type_id.name", "=", "Receivable"),
],
limit=1,
)
self.income_account = self.env["account.account"].search(
[
("company_id", "=", self.company.id),
("user_type_id.name", "=", "Income"),
],
limit=1,
)
self.tax_account = self.env["account.account"].search(
[
("company_id", "=", self.company.id),
(
"user_type_id",
"=",
self.env.ref(
"account.data_account_type_non_current_liabilities"
).id,
),
],
limit=1,
)
self.bank_journal = self.env["account.journal"].search(
[("type", "=", "bank"), ("company_id", "=", self.company.id)], limit=1
)
self.tax_tag_01 = self.env["account.account.tag"].create(
{"name": "Tag 01", "applicability": "taxes"}
)
self.tax_tag_02 = self.env["account.account.tag"].create(
{"name": "Tag 02", "applicability": "taxes"}
)
self.tax_tag_03 = self.env["account.account.tag"].create(
{"name": "Tag 03", "applicability": "taxes"}
)
self.tax_group_10 = self.env["account.tax.group"].create(
{"name": "Tax 10%", "sequence": 1}
)
self.tax_group_20 = self.env["account.tax.group"].create(
{"name": "Tax 20%", "sequence": 2}
)
self.tax_10 = self.env["account.tax"].create(
{
"name": "Tax 10.0%",
"amount": 10.0,
"amount_type": "percent",
"type_tax_use": "sale",
"account_id": self.tax_account.id,
"company_id": self.company.id,
"refund_account_id": self.tax_account.id,
"tax_group_id": self.tax_group_10.id,
"tag_ids": [(6, 0, [self.tax_tag_01.id, self.tax_tag_02.id])],
}
)
self.tax_20 = self.env["account.tax"].create(
{
"sequence": 30,
"name": "Tax 20.0%",
"amount": 20.0,
"amount_type": "percent",
"type_tax_use": "sale",
"tax_exigibility": "on_payment",
"account_id": self.tax_account.id,
"company_id": self.company.id,
"refund_account_id": self.tax_account.id,
"cash_basis_account_id": self.tax_account.id,
"tax_group_id": self.tax_group_20.id,
"tag_ids": [(6, 0, [self.tax_tag_02.id, self.tax_tag_03.id])],
}
)
invoice = self.env['account.invoice'].create({
'partner_id': self.env.ref('base.res_partner_2').id,
'account_id': self.receivable_account.id,
'company_id': self.company.id,
'date_invoice': time.strftime('%Y-%m-03'),
'type': 'out_invoice',
})
invoice = self.env["account.invoice"].create(
{
"partner_id": self.env.ref("base.res_partner_2").id,
"account_id": self.receivable_account.id,
"company_id": self.company.id,
"date_invoice": time.strftime("%Y-%m-03"),
"type": "out_invoice",
}
)
self.env['account.invoice.line'].create({
'product_id': self.env.ref('product.product_product_4').id,
'quantity': 1.0,
'price_unit': 100.0,
'invoice_id': invoice.id,
'name': 'product',
'account_id': self.income_account.id,
'invoice_line_tax_ids': [(6, 0, [self.tax_10.id])],
})
self.env["account.invoice.line"].create(
{
"product_id": self.env.ref("product.product_product_4").id,
"quantity": 1.0,
"price_unit": 100.0,
"invoice_id": invoice.id,
"name": "product",
"account_id": self.income_account.id,
"invoice_line_tax_ids": [(6, 0, [self.tax_10.id])],
}
)
invoice.compute_taxes()
invoice.action_invoice_open()
self.cbinvoice = self.env['account.invoice'].create({
'partner_id': self.env.ref('base.res_partner_2').id,
'account_id': self.receivable_account.id,
'company_id': self.company.id,
'date_invoice': time.strftime('%Y-%m-05'),
'type': 'out_invoice',
})
self.cbinvoice = self.env["account.invoice"].create(
{
"partner_id": self.env.ref("base.res_partner_2").id,
"account_id": self.receivable_account.id,
"company_id": self.company.id,
"date_invoice": time.strftime("%Y-%m-05"),
"type": "out_invoice",
}
)
self.env['account.invoice.line'].create({
'product_id': self.env.ref('product.product_product_4').id,
'quantity': 1.0,
'price_unit': 500.0,
'invoice_id': self.cbinvoice.id,
'name': 'product',
'account_id': self.income_account.id,
'invoice_line_tax_ids': [(6, 0, [self.tax_20.id])],
})
self.env["account.invoice.line"].create(
{
"product_id": self.env.ref("product.product_product_4").id,
"quantity": 1.0,
"price_unit": 500.0,
"invoice_id": self.cbinvoice.id,
"name": "product",
"account_id": self.income_account.id,
"invoice_line_tax_ids": [(6, 0, [self.tax_20.id])],
}
)
self.cbinvoice.compute_taxes()
self.cbinvoice.action_invoice_open()
self.cbinvoice.pay_and_reconcile(
self.bank_journal.id, 300, date(
date.today().year, date.today().month, 10))
self.bank_journal.id, 300, date(date.today().year, date.today().month, 10)
)
def _get_report_lines(self, taxgroups=False):
based_on = 'taxtags'
based_on = "taxtags"
if taxgroups:
based_on = 'taxgroups'
vat_report = self.env['vat.report.wizard'].create({
'date_from': self.date_from,
'date_to': self.date_to,
'company_id': self.company.id,
'based_on': based_on,
'tax_detail': True,
})
based_on = "taxgroups"
vat_report = self.env["vat.report.wizard"].create(
{
"date_from": self.date_from,
"date_to": self.date_to,
"company_id": self.company.id,
"based_on": based_on,
"tax_detail": True,
}
)
data = vat_report._prepare_vat_report()
res_data = self.env[
'report.account_financial_report.vat_report'
"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:
if tag_or_group["name"] == tag_or_group_name:
tag_or_group_in_report = True
break
return tag_or_group_in_report
@ -150,9 +171,9 @@ class TestVATReport(common.TransactionCase):
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:
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
@ -160,54 +181,56 @@ class TestVATReport(common.TransactionCase):
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']
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']
if tag_or_group["taxes"]:
for tax in tag_or_group["taxes"]:
if tax["name"] == tax_name:
tax_net = tax["net"]
tax_tax = tax["tax"]
return tax_net, tax_tax
def test_01_compute(self):
# Generate the vat lines
res_data = self._get_report_lines()
vat_report = res_data['vat_report']
vat_report = res_data["vat_report"]
# Check report based on taxtags
check_tax_tag_01 = self.check_tag_or_group_in_report(
self.tax_tag_01.name, vat_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.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.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)
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)
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)
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)
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.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)
@ -222,29 +245,29 @@ class TestVATReport(common.TransactionCase):
# Check report based on taxgroups
res_data = self._get_report_lines(taxgroups=True)
vat_report = res_data['vat_report']
vat_report = res_data["vat_report"]
check_group_10 = self.check_tag_or_group_in_report(
self.tax_group_10.name, vat_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.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)
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)
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)
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.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)
@ -256,44 +279,55 @@ class TestVATReport(common.TransactionCase):
self.assertEqual(tax_20_tax, 50)
def test_wizard_date_range(self):
vat_wizard = self.env['vat.report.wizard']
date_range = self.env['date.range']
self.type = self.env['date.range.type'].create(
{'name': 'Month',
'company_id': False,
'allow_overlap': False})
dt = date_range.create({
'name': 'FS2016',
'date_start': time.strftime('%Y-%m-01'),
'date_end': time.strftime('%Y-%m-28'),
'type_id': self.type.id,
})
vat_wizard = self.env["vat.report.wizard"]
date_range = self.env["date.range"]
self.type = self.env["date.range.type"].create(
{"name": "Month", "company_id": False, "allow_overlap": False}
)
dt = date_range.create(
{
"name": "FS2016",
"date_start": time.strftime("%Y-%m-01"),
"date_end": time.strftime("%Y-%m-28"),
"type_id": self.type.id,
}
)
wizard = vat_wizard.create(
{'date_range_id': dt.id,
'date_from': time.strftime('%Y-%m-28'),
'date_to': time.strftime('%Y-%m-01'),
'tax_detail': True})
{
"date_range_id": dt.id,
"date_from": time.strftime("%Y-%m-28"),
"date_to": time.strftime("%Y-%m-01"),
"tax_detail": True,
}
)
wizard.onchange_date_range_id()
self.assertEqual(wizard.date_from, date(
date.today().year, date.today().month, 1))
self.assertEqual(wizard.date_to, date(
date.today().year, date.today().month, 28))
wizard._export('qweb-pdf')
self.assertEqual(
wizard.date_from, date(date.today().year, date.today().month, 1)
)
self.assertEqual(
wizard.date_to, date(date.today().year, date.today().month, 28)
)
wizard._export("qweb-pdf")
wizard.button_export_html()
wizard.button_export_pdf()
wizard.button_export_xlsx()
wizard = vat_wizard.create(
{'date_range_id': dt.id,
'date_from': time.strftime('%Y-%m-28'),
'date_to': time.strftime('%Y-%m-01'),
'based_on': 'taxgroups',
'tax_detail': True})
{
"date_range_id": dt.id,
"date_from": time.strftime("%Y-%m-28"),
"date_to": time.strftime("%Y-%m-01"),
"based_on": "taxgroups",
"tax_detail": True,
}
)
wizard.onchange_date_range_id()
self.assertEqual(wizard.date_from, date(
date.today().year, date.today().month, 1))
self.assertEqual(wizard.date_to, date(
date.today().year, date.today().month, 28))
wizard._export('qweb-pdf')
self.assertEqual(
wizard.date_from, date(date.today().year, date.today().month, 1)
)
self.assertEqual(
wizard.date_to, date(date.today().year, date.today().month, 28)
)
wizard._export("qweb-pdf")
wizard.button_export_html()
wizard.button_export_pdf()
wizard.button_export_xlsx()

6
account_financial_report/view/account_view.xml

@ -1,13 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record model="ir.ui.view" id="view_account_specific_form">
<field name="name">account.account.form.inherit</field>
<field name="inherit_id" ref="account.view_account_form"/>
<field name="inherit_id" ref="account.view_account_form" />
<field name="model">account.account</field>
<field name="type">form</field>
<field name="arch" type="xml">
<field name="deprecated" position="after">
<field name="centralized"/>
<field name="centralized" />
</field>
</field>
</record>

6
account_financial_report/view/report_aged_partner_balance.xml

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_aged_partner_balance">
<div class="o_account_financial_reports_page">
<t t-call="account_financial_report.report_buttons"/>
<t t-call="account_financial_report.report_aged_partner_balance_base"/>
<t t-call="account_financial_report.report_buttons" />
<t t-call="account_financial_report.report_aged_partner_balance_base" />
</div>
</template>
</odoo>

6
account_financial_report/view/report_general_ledger.xml

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_general_ledger">
<div class="o_account_financial_reports_page">
<t t-call="account_financial_report.report_buttons"/>
<t t-call="account_financial_report.report_general_ledger_base"/>
<t t-call="account_financial_report.report_buttons" />
<t t-call="account_financial_report.report_general_ledger_base" />
</div>
</template>
</odoo>

6
account_financial_report/view/report_journal_ledger.xml

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_journal_ledger">
<div class="o_account_financial_reports_page">
<t t-call="account_financial_report.report_buttons"/>
<t t-call="account_financial_report.report_journal_ledger_base"/>
<t t-call="account_financial_report.report_buttons" />
<t t-call="account_financial_report.report_journal_ledger_base" />
</div>
</template>
</odoo>

6
account_financial_report/view/report_open_items.xml

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_open_items">
<div class="o_account_financial_reports_page">
<t t-call="account_financial_report.report_buttons"/>
<t t-call="account_financial_report.report_open_items_base"/>
<t t-call="account_financial_report.report_buttons" />
<t t-call="account_financial_report.report_open_items_base" />
</div>
</template>
</odoo>

83
account_financial_report/view/report_template.xml

@ -1,58 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="account_financial_report_assets_backend"
name="account_financial_report assets" inherit_id="web.assets_backend">
<template
id="account_financial_report_assets_backend"
name="account_financial_report assets"
inherit_id="web.assets_backend"
>
<xpath expr="." position="inside">
<link href="/account_financial_report/static/src/css/report.css" rel="stylesheet"/>
<script type="text/javascript"
src="/account_financial_report/static/src/js/account_financial_report_backend.js"/>
<script type="text/javascript"
src="/account_financial_report/static/src/js/account_financial_report_widgets.js"/>
<link
href="/account_financial_report/static/src/css/report.css"
rel="stylesheet"
/>
<script
type="text/javascript"
src="/account_financial_report/static/src/js/account_financial_report_backend.js"
/>
<script
type="text/javascript"
src="/account_financial_report/static/src/js/account_financial_report_widgets.js"
/>
</xpath>
</template>
<template id="report_buttons">
<div class="button_row">
<button class="o_account_financial_reports_print btn btn-sm oe_button"><span class="fa fa-print"/> Print</button>
<button class="o_account_financial_reports_export btn btn-sm oe_button"><span class="fa fa-download"/> Export</button>
<button class="o_account_financial_reports_print btn btn-sm oe_button"><span
class="fa fa-print"
/> Print</button>
<button
class="o_account_financial_reports_export btn btn-sm oe_button"
><span class="fa fa-download" /> Export</button>
</div>
</template>
<record id="action_report_general_ledger" model="ir.actions.client">
<field name="name">General Ledger</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'model': 'report.account_financial_report.general_ledger'}" />
<field
name="context"
eval="{'model': 'report.account_financial_report.general_ledger'}"
/>
</record>
<record id="action_report_journal_ledger" model="ir.actions.client">
<field name="name">Journal</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'model': 'report.account_financial_report.journal_ledger'}" />
<field
name="context"
eval="{'model': 'report.account_financial_report.journal_ledger'}"
/>
</record>
<record id="action_report_open_items" model="ir.actions.client">
<field name="name">Open Items</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'model': 'report.account_financial_report.open_items'}" />
<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="{'model': 'report.account_financial_report.open_items'}"
/>
</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="tag">account_financial_report_backend</field>
<field name="context" eval="{'model': 'report.account_financial_report.trial_balance'}" />
<field
name="context"
eval="{'model': 'report.account_financial_report.trial_balance'}"
/>
</record>
<record id="action_report_aged_partner_balance" model="ir.actions.client">
<record id="action_report_aged_partner_balance" model="ir.actions.client">
<field name="name">Aged Partner Balance</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'model': 'report.account_financial_report.aged_partner_balance'}" />
<field
name="context"
eval="{'model': 'report.account_financial_report.aged_partner_balance'}"
/>
</record>
<record id="action_report_vat_report" model="ir.actions.client">
<field name="name">VAT Report</field>
<field name="tag">account_financial_report_backend</field>
<field name="context" eval="{'model': 'report.account_financial_report.vat_report'}" />
<field
name="context"
eval="{'model': 'report.account_financial_report.vat_report'}"
/>
</record>
</odoo>

8
account_financial_report/view/report_trial_balance.xml

@ -1,11 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_trial_balance">
<div class="o_account_financial_reports_page">
<t t-call="account_financial_report.report_buttons"/>
<t t-call="account_financial_report.report_trial_balance_base"/>
<t t-call="account_financial_report.report_buttons" />
<t t-call="account_financial_report.report_trial_balance_base" />
</div>
</template>
</odoo>

6
account_financial_report/view/report_vat_report.xml

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<template id="report_vat_report">
<div class="o_account_financial_reports_page">
<t t-call="account_financial_report.report_buttons"/>
<t t-call="account_financial_report.report_vat_report_base"/>
<t t-call="account_financial_report.report_buttons" />
<t t-call="account_financial_report.report_vat_report_base" />
</div>
</template>
</odoo>

29
account_financial_report/wizard/abstract_wizard.py

@ -5,28 +5,25 @@ from odoo import models
class AbstractWizard(models.AbstractModel):
_name = 'account_financial_report_abstract_wizard'
_description = 'Abstract Wizard'
_name = "account_financial_report_abstract_wizard"
_description = "Abstract Wizard"
def _get_partner_ids_domain(self):
return [
'&',
'|',
('company_id', '=', self.company_id.id),
('company_id', '=', False),
'|',
('parent_id', '=', False),
('is_company', '=', True),
"&",
"|",
("company_id", "=", self.company_id.id),
("company_id", "=", False),
"|",
("parent_id", "=", False),
("is_company", "=", True),
]
def _default_partners(self):
context = self.env.context
if (
context.get('active_ids') and
context.get('active_model') == 'res.partner'
):
partners = self.env['res.partner'].browse(context['active_ids'])
corp_partners = partners.filtered('parent_id')
if context.get("active_ids") and context.get("active_model") == "res.partner":
partners = self.env["res.partner"].browse(context["active_ids"])
corp_partners = partners.filtered("parent_id")
partners -= corp_partners
partners |= corp_partners.mapped('commercial_partner_id')
partners |= corp_partners.mapped("commercial_partner_id")
return partners.ids

99
account_financial_report/wizard/aged_partner_balance_wizard.py

@ -9,114 +9,115 @@ from odoo import api, fields, models
class AgedPartnerBalanceWizard(models.TransientModel):
"""Aged partner balance report wizard."""
_name = 'aged.partner.balance.report.wizard'
_description = 'Aged Partner Balance Wizard'
_inherit = 'account_financial_report_abstract_wizard'
_name = "aged.partner.balance.report.wizard"
_description = "Aged Partner Balance Wizard"
_inherit = "account_financial_report_abstract_wizard"
company_id = fields.Many2one(
comodel_name='res.company',
comodel_name="res.company",
default=lambda self: self.env.user.company_id,
required=False,
string='Company'
string="Company",
)
date_at = fields.Date(required=True, default=fields.Date.context_today)
target_move = fields.Selection(
[("posted", "All Posted Entries"), ("all", "All Entries")],
string="Target Moves",
required=True,
default="all",
)
date_at = fields.Date(required=True,
default=fields.Date.context_today)
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')],
string='Target Moves',
required=True,
default='all')
account_ids = fields.Many2many(
comodel_name='account.account',
string='Filter accounts',
comodel_name="account.account", string="Filter accounts",
)
receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean()
partner_ids = fields.Many2many(
comodel_name='res.partner',
string='Filter partners',
comodel_name="res.partner", string="Filter partners",
)
show_move_line_details = fields.Boolean()
@api.onchange('company_id')
@api.onchange("company_id")
def onchange_company_id(self):
"""Handle company change."""
if self.company_id and self.partner_ids:
self.partner_ids = self.partner_ids.filtered(
lambda p: p.company_id == self.company_id or
not p.company_id)
lambda p: p.company_id == self.company_id or not p.company_id
)
if self.company_id and self.account_ids:
if self.receivable_accounts_only or self.payable_accounts_only:
self.onchange_type_accounts_only()
else:
self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id)
res = {'domain': {'account_ids': [],
'partner_ids': []}}
lambda a: a.company_id == self.company_id
)
res = {"domain": {"account_ids": [], "partner_ids": []}}
if not self.company_id:
return res
else:
res['domain']['account_ids'] += [
('company_id', '=', self.company_id.id)]
res['domain']['partner_ids'] += self._get_partner_ids_domain()
res["domain"]["account_ids"] += [("company_id", "=", self.company_id.id)]
res["domain"]["partner_ids"] += self._get_partner_ids_domain()
return res
@api.onchange('receivable_accounts_only', 'payable_accounts_only')
@api.onchange("receivable_accounts_only", "payable_accounts_only")
def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change."""
domain = [('company_id', '=', self.company_id.id)]
domain = [("company_id", "=", self.company_id.id)]
if self.receivable_accounts_only or 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:
domain += [('internal_type', '=', 'receivable')]
domain += [("internal_type", "=", "receivable")]
elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')]
domain += [("internal_type", "=", "payable")]
elif not self.receivable_accounts_only and not self.payable_accounts_only:
domain += [('reconcile', '=', True)]
self.account_ids = self.env['account.account'].search(domain)
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'
if report_type == "xlsx":
report_name = "a_f_r.report_aged_partner_balance_xlsx"
else:
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)
report_name = "account_financial_report.aged_partner_balance"
return (
self.env["ir.actions.report"]
.search(
[("report_name", "=", report_name), ("report_type", "=", report_type)],
limit=1,
)
.report_action(self, data=data)
)
@api.multi
def button_export_html(self):
self.ensure_one()
report_type = 'qweb-html'
report_type = "qweb-html"
return self._export(report_type)
@api.multi
def button_export_pdf(self):
self.ensure_one()
report_type = 'qweb-pdf'
report_type = "qweb-pdf"
return self._export(report_type)
@api.multi
def button_export_xlsx(self):
self.ensure_one()
report_type = 'xlsx'
report_type = "xlsx"
return self._export(report_type)
def _prepare_report_aged_partner_balance(self):
self.ensure_one()
return {
'wizard_id': self.id,
'date_at': self.date_at,
'only_posted_moves': self.target_move == 'posted',
'company_id': self.company_id.id,
'account_ids': self.account_ids.ids,
'partner_ids': self.partner_ids.ids,
'show_move_line_details': self.show_move_line_details,
"wizard_id": self.id,
"date_at": self.date_at,
"only_posted_moves": self.target_move == "posted",
"company_id": self.company_id.id,
"account_ids": self.account_ids.ids,
"partner_ids": self.partner_ids.ids,
"show_move_line_details": self.show_move_line_details,
}
def _export(self, report_type):

82
account_financial_report/wizard/aged_partner_balance_wizard_view.xml

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- AGED PARTNER BALANCE -->
<record id="aged_partner_balance_wizard" model="ir.ui.view">
<field name="name">Aged Partner Balance</field>
@ -8,52 +7,75 @@
<field name="arch" type="xml">
<form>
<group name="main_info">
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field
name="company_id"
options="{'no_create': True}"
groups="base.group_multi_company"
/>
</group>
<group name="filters">
<group name="date_range">
<field name="date_at"/>
<field name="date_at" />
</group>
<group name="other_filters">
<field name="target_move" widget="radio"/>
<field name="show_move_line_details"/>
<field name="target_move" widget="radio" />
<field name="show_move_line_details" />
</group>
</group>
<group name="partner_filter" col="1">
<label for="partner_ids"/>
<field name="partner_ids" nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"/>
<label for="partner_ids" />
<field
name="partner_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
/>
</group>
<group name="account_filter" col="4">
<label for="account_ids" colspan="4"/>
<field name="receivable_accounts_only"/>
<field name="payable_accounts_only"/>
<field name="account_ids" nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
colspan="4"/>
<label for="account_ids" colspan="4" />
<field name="receivable_accounts_only" />
<field name="payable_accounts_only" />
<field
name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
colspan="4"
/>
</group>
<footer>
<button name="button_export_html" string="View"
type="object" default_focus="1" class="oe_highlight"/>
<button
name="button_export_html"
string="View"
type="object"
default_focus="1"
class="oe_highlight"
/>
or
<button name="button_export_pdf" string="Export PDF" type="object"/>
<button
name="button_export_pdf"
string="Export PDF"
type="object"
/>
or
<button name="button_export_xlsx" string="Export XLSX" type="object"/>
<button
name="button_export_xlsx"
string="Export XLSX"
type="object"
/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<act_window id="action_aged_partner_balance_wizard"
name="Aged Partner Balance"
res_model="aged.partner.balance.report.wizard"
view_type="form"
view_mode="form"
view_id="aged_partner_balance_wizard"
target="new" />
<act_window
id="action_aged_partner_balance_wizard"
name="Aged Partner Balance"
res_model="aged.partner.balance.report.wizard"
view_type="form"
view_mode="form"
view_id="aged_partner_balance_wizard"
target="new"
/>
</odoo>

275
account_financial_report/wizard/general_ledger_wizard.py

@ -7,83 +7,72 @@
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import api, fields, models, _
from odoo.exceptions import ValidationError
import time
from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
class GeneralLedgerReportWizard(models.TransientModel):
"""General ledger report wizard."""
_name = "general.ledger.report.wizard"
_description = "General Ledger Report Wizard"
_inherit = 'account_financial_report_abstract_wizard'
_inherit = "account_financial_report_abstract_wizard"
company_id = fields.Many2one(
comodel_name='res.company',
comodel_name="res.company",
default=lambda self: self.env.user.company_id,
required=False,
string='Company'
string="Company",
)
date_range_id = fields.Many2one(
comodel_name='date.range',
string='Date range'
date_range_id = fields.Many2one(comodel_name="date.range", string="Date range")
date_from = fields.Date(required=True, default=lambda self: self._init_date_from())
date_to = fields.Date(required=True, default=fields.Date.context_today)
fy_start_date = fields.Date(compute="_compute_fy_start_date")
target_move = fields.Selection(
[("posted", "All Posted Entries"), ("all", "All Entries")],
string="Target Moves",
required=True,
default="all",
)
date_from = fields.Date(required=True,
default=lambda self: self._init_date_from())
date_to = fields.Date(required=True,
default=fields.Date.context_today)
fy_start_date = fields.Date(compute='_compute_fy_start_date')
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')],
string='Target Moves',
required=True,
default='all')
account_ids = fields.Many2many(
comodel_name='account.account',
string='Filter accounts',
comodel_name="account.account", string="Filter accounts",
)
centralize = fields.Boolean(string='Activate centralization',
default=True)
centralize = fields.Boolean(string="Activate centralization", default=True)
hide_account_at_0 = fields.Boolean(
string='Hide account ending balance at 0',
help='Use this filter to hide an account or a partner '
'with an ending balance at 0. '
'If partners are filtered, '
'debits and credits totals will not match the trial balance.'
)
show_analytic_tags = fields.Boolean(
string='Show analytic tags',
string="Hide account ending balance at 0",
help="Use this filter to hide an account or a partner "
"with an ending balance at 0. "
"If partners are filtered, "
"debits and credits totals will not match the trial balance.",
)
show_analytic_tags = fields.Boolean(string="Show analytic tags",)
receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean()
partner_ids = fields.Many2many(
comodel_name='res.partner',
string='Filter partners',
comodel_name="res.partner",
string="Filter partners",
default=lambda self: self._default_partners(),
)
analytic_tag_ids = fields.Many2many(
comodel_name='account.analytic.tag',
string='Filter analytic tags',
comodel_name="account.analytic.tag", string="Filter analytic tags",
)
account_journal_ids = fields.Many2many(
comodel_name='account.journal',
string='Filter journals',
comodel_name="account.journal", string="Filter journals",
)
cost_center_ids = fields.Many2many(
comodel_name='account.analytic.account',
string='Filter cost centers',
comodel_name="account.analytic.account", string="Filter cost centers",
)
not_only_one_unaffected_earnings_account = fields.Boolean(
readonly=True,
string='Not only one unaffected earnings account'
readonly=True, string="Not only one unaffected earnings account"
)
foreign_currency = fields.Boolean(
string='Show foreign currency',
help='Display foreign currency for move lines, unless '
'account currency is not setup through chart of accounts '
'will display initial and final balance in that currency.',
string="Show foreign currency",
help="Display foreign currency for move lines, unless "
"account currency is not setup through chart of accounts "
"will display initial and final balance in that currency.",
default=lambda self: self._default_foreign_currency(),
)
@ -95,73 +84,87 @@ class GeneralLedgerReportWizard(models.TransientModel):
last_fsc_month = self.env.user.company_id.fiscalyear_last_month
last_fsc_day = self.env.user.company_id.fiscalyear_last_day
if cur_month < last_fsc_month \
or cur_month == last_fsc_month and cur_day <= last_fsc_day:
return time.strftime('%Y-01-01')
if (
cur_month < last_fsc_month
or cur_month == last_fsc_month
and cur_day <= last_fsc_day
):
return time.strftime("%Y-01-01")
def _default_foreign_currency(self):
return self.env.user.has_group('base.group_multi_currency')
return self.env.user.has_group("base.group_multi_currency")
@api.depends('date_from')
@api.depends("date_from")
def _compute_fy_start_date(self):
for wiz in self.filtered('date_from'):
for wiz in self.filtered("date_from"):
date = fields.Datetime.from_string(wiz.date_from)
res = self.company_id.compute_fiscalyear_dates(date)
wiz.fy_start_date = fields.Date.to_string(res['date_from'])
wiz.fy_start_date = fields.Date.to_string(res["date_from"])
@api.onchange('company_id')
@api.onchange("company_id")
def onchange_company_id(self):
"""Handle company change."""
account_type = self.env.ref('account.data_unaffected_earnings')
count = self.env['account.account'].search_count(
account_type = self.env.ref("account.data_unaffected_earnings")
count = self.env["account.account"].search_count(
[
('user_type_id', '=', account_type.id),
('company_id', '=', self.company_id.id)
])
("user_type_id", "=", account_type.id),
("company_id", "=", self.company_id.id),
]
)
self.not_only_one_unaffected_earnings_account = count != 1
if self.company_id and self.date_range_id.company_id and \
self.date_range_id.company_id != self.company_id:
if (
self.company_id
and self.date_range_id.company_id
and self.date_range_id.company_id != self.company_id
):
self.date_range_id = False
if self.company_id and self.account_journal_ids:
self.account_journal_ids = self.account_journal_ids.filtered(
lambda p: p.company_id == self.company_id or
not p.company_id)
lambda p: p.company_id == self.company_id or not p.company_id
)
if self.company_id and self.partner_ids:
self.partner_ids = self.partner_ids.filtered(
lambda p: p.company_id == self.company_id or
not p.company_id)
lambda p: p.company_id == self.company_id or not p.company_id
)
if self.company_id and self.account_ids:
if self.receivable_accounts_only or self.payable_accounts_only:
self.onchange_type_accounts_only()
else:
self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id)
lambda a: a.company_id == self.company_id
)
if self.company_id and self.cost_center_ids:
self.cost_center_ids = self.cost_center_ids.filtered(
lambda c: c.company_id == self.company_id)
res = {'domain': {'account_ids': [],
'partner_ids': [],
'account_journal_ids': [],
'cost_center_ids': [],
'date_range_id': []
}
}
lambda c: c.company_id == self.company_id
)
res = {
"domain": {
"account_ids": [],
"partner_ids": [],
"account_journal_ids": [],
"cost_center_ids": [],
"date_range_id": [],
}
}
if not self.company_id:
return res
else:
res['domain']['account_ids'] += [
('company_id', '=', self.company_id.id)]
res['domain']['account_journal_ids'] += [
('company_id', '=', self.company_id.id)]
res['domain']['partner_ids'] += self._get_partner_ids_domain()
res['domain']['cost_center_ids'] += [
('company_id', '=', self.company_id.id)]
res['domain']['date_range_id'] += [
'|', ('company_id', '=', self.company_id.id),
('company_id', '=', False)]
res["domain"]["account_ids"] += [("company_id", "=", self.company_id.id)]
res["domain"]["account_journal_ids"] += [
("company_id", "=", self.company_id.id)
]
res["domain"]["partner_ids"] += self._get_partner_ids_domain()
res["domain"]["cost_center_ids"] += [
("company_id", "=", self.company_id.id)
]
res["domain"]["date_range_id"] += [
"|",
("company_id", "=", self.company_id.id),
("company_id", "=", False),
]
return res
@api.onchange('date_range_id')
@api.onchange("date_range_id")
def onchange_date_range_id(self):
"""Handle date range change."""
if self.date_range_id:
@ -169,31 +172,37 @@ class GeneralLedgerReportWizard(models.TransientModel):
self.date_to = self.date_range_id.date_end
@api.multi
@api.constrains('company_id', 'date_range_id')
@api.constrains("company_id", "date_range_id")
def _check_company_id_date_range_id(self):
for rec in self.sudo():
if rec.company_id and rec.date_range_id.company_id and\
rec.company_id != rec.date_range_id.company_id:
if (
rec.company_id
and rec.date_range_id.company_id
and rec.company_id != rec.date_range_id.company_id
):
raise ValidationError(
_('The Company in the General Ledger Report Wizard and in '
'Date Range must be the same.'))
_(
"The Company in the General Ledger Report Wizard and in "
"Date Range must be the same."
)
)
@api.onchange('receivable_accounts_only', 'payable_accounts_only')
@api.onchange("receivable_accounts_only", "payable_accounts_only")
def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change."""
if self.receivable_accounts_only or self.payable_accounts_only:
domain = [('company_id', '=', self.company_id.id)]
domain = [("company_id", "=", self.company_id.id)]
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:
domain += [('internal_type', '=', 'receivable')]
domain += [("internal_type", "=", "receivable")]
elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')]
self.account_ids = self.env['account.account'].search(domain)
domain += [("internal_type", "=", "payable")]
self.account_ids = self.env["account.account"].search(domain)
else:
self.account_ids = None
@api.onchange('partner_ids')
@api.onchange("partner_ids")
def onchange_partner_ids(self):
"""Handle partners change."""
if self.partner_ids:
@ -202,73 +211,77 @@ class GeneralLedgerReportWizard(models.TransientModel):
self.receivable_accounts_only = self.payable_accounts_only = False
@api.multi
@api.depends('company_id')
@api.depends("company_id")
def _compute_unaffected_earnings_account(self):
account_type = self.env.ref('account.data_unaffected_earnings')
account_type = self.env.ref("account.data_unaffected_earnings")
for record in self:
record.unaffected_earnings_account = self.env[
'account.account'].search(
record.unaffected_earnings_account = self.env["account.account"].search(
[
('user_type_id', '=', account_type.id),
('company_id', '=', record.company_id.id)
])
("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
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'
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)
report_name = "account_financial_report.general_ledger"
return (
self.env["ir.actions.report"]
.search(
[("report_name", "=", report_name), ("report_type", "=", report_type)],
limit=1,
)
.report_action(self, data=data)
)
@api.multi
def button_export_html(self):
self.ensure_one()
report_type = 'qweb-html'
report_type = "qweb-html"
return self._export(report_type)
@api.multi
def button_export_pdf(self):
self.ensure_one()
report_type = 'qweb-pdf'
report_type = "qweb-pdf"
return self._export(report_type)
@api.multi
def button_export_xlsx(self):
self.ensure_one()
report_type = 'xlsx'
report_type = "xlsx"
return self._export(report_type)
def _prepare_report_general_ledger(self):
self.ensure_one()
return {
'wizard_id': self.id,
'date_from': self.date_from,
'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted',
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency,
'show_analytic_tags': self.show_analytic_tags,
'company_id': self.company_id.id,
'account_ids': self.account_ids.ids,
'partner_ids': self.partner_ids.ids,
'cost_center_ids': self.cost_center_ids.ids,
'analytic_tag_ids': self.analytic_tag_ids.ids,
'journal_ids': self.account_journal_ids.ids,
'centralize': self.centralize,
'fy_start_date': self.fy_start_date,
'unaffected_earnings_account': self.unaffected_earnings_account.id,
"wizard_id": self.id,
"date_from": self.date_from,
"date_to": self.date_to,
"only_posted_moves": self.target_move == "posted",
"hide_account_at_0": self.hide_account_at_0,
"foreign_currency": self.foreign_currency,
"show_analytic_tags": self.show_analytic_tags,
"company_id": self.company_id.id,
"account_ids": self.account_ids.ids,
"partner_ids": self.partner_ids.ids,
"cost_center_ids": self.cost_center_ids.ids,
"analytic_tag_ids": self.analytic_tag_ids.ids,
"journal_ids": self.account_journal_ids.ids,
"centralize": self.centralize,
"fy_start_date": self.fy_start_date,
"unaffected_earnings_account": self.unaffected_earnings_account.id,
}
def _export(self, report_type):

159
account_financial_report/wizard/general_ledger_wizard_view.xml

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- GENERAL LEDGER -->
<record id="general_ledger_wizard" model="ir.ui.view">
<field name="name">General Ledger</field>
@ -8,95 +7,141 @@
<field name="arch" type="xml">
<form>
<group name="main_info">
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field
name="company_id"
options="{'no_create': True}"
groups="base.group_multi_company"
/>
</group>
<div attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', True)]}">
<div
attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', True)]}"
>
<group name="filters">
<group name="date_range">
<field name="date_range_id"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="fy_start_date" invisible="1"/>
<field name="date_range_id" />
<field name="date_from" />
<field name="date_to" />
<field name="fy_start_date" invisible="1" />
</group>
<group name="other_filters">
<field name="target_move" widget="radio"/>
<field name="centralize"/>
<field name="hide_account_at_0"/>
<field name="foreign_currency"/>
<field name="show_analytic_tags"/>
<field name="target_move" widget="radio" />
<field name="centralize" />
<field name="hide_account_at_0" />
<field name="foreign_currency" />
<field name="show_analytic_tags" />
</group>
</group>
<notebook>
<page string="Filter accounts">
<group col="4">
<field name="receivable_accounts_only"/>
<field name="payable_accounts_only"/>
<field name="receivable_accounts_only" />
<field name="payable_accounts_only" />
</group>
<field name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"/>
<field
name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
/>
</page>
<page string="Filter partners">
<field name="partner_ids" nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"/>
<field
name="partner_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
/>
</page>
<page string="Filter cost centers" groups="analytic.group_analytic_accounting">
<field name="cost_center_ids" nolabel="1"
options="{'no_create': True}"
groups="analytic.group_analytic_accounting"/>
<page
string="Filter cost centers"
groups="analytic.group_analytic_accounting"
>
<field
name="cost_center_ids"
nolabel="1"
options="{'no_create': True}"
groups="analytic.group_analytic_accounting"
/>
</page>
<page string="Filter analytic tags">
<field name="analytic_tag_ids" widget="many2many_tags" nolabel="1" options="{'no_create': True}"/>
<field
name="analytic_tag_ids"
widget="many2many_tags"
nolabel="1"
options="{'no_create': True}"
/>
</page>
</notebook>
</div>
<div attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', False)]}">
<field name="not_only_one_unaffected_earnings_account" invisible="1"/>
<group/>
<h4>General Ledger can be computed only if selected company have only one unaffected earnings account.</h4>
<group/>
<div
attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', False)]}"
>
<field
name="not_only_one_unaffected_earnings_account"
invisible="1"
/>
<group />
<h4
>General Ledger can be computed only if selected company have only one unaffected earnings account.</h4>
<group />
</div>
<footer>
<div attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', True)]}">
<button name="button_export_html" string="View"
type="object" default_focus="1" class="oe_highlight"/>
<div
attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', True)]}"
>
<button
name="button_export_html"
string="View"
type="object"
default_focus="1"
class="oe_highlight"
/>
or
<button name="button_export_pdf" string="Export PDF" type="object"/>
<button
name="button_export_pdf"
string="Export PDF"
type="object"
/>
or
<button name="button_export_xlsx" string="Export XLSX" type="object"/>
<button
name="button_export_xlsx"
string="Export XLSX"
type="object"
/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</div>
<div attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', False)]}">
<div
attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', False)]}"
>
<button string="Cancel" class="oe_link" special="cancel" />
</div>
</footer>
</form>
</field>
</record>
<act_window id="action_general_ledger_wizard"
name="General Ledger"
res_model="general.ledger.report.wizard"
view_type="form"
view_mode="form"
view_id="general_ledger_wizard"
target="new" />
<act_window
id="action_general_ledger_wizard"
name="General Ledger"
res_model="general.ledger.report.wizard"
view_type="form"
view_mode="form"
view_id="general_ledger_wizard"
target="new"
/>
<!--Add to res.partner action-->
<act_window id="act_action_general_ledger_wizard_partner_relation"
name="General Ledger"
res_model="general.ledger.report.wizard"
src_model="res.partner"
view_mode="form"
context="{
<act_window
id="act_action_general_ledger_wizard_partner_relation"
name="General Ledger"
res_model="general.ledger.report.wizard"
src_model="res.partner"
view_mode="form"
context="{
'default_receivable_accounts_only':1,
'default_payable_accounts_only':1,
}"
groups="account.group_account_manager"
key2="client_action_multi"
target="new" />
groups="account.group_account_manager"
key2="client_action_multi"
target="new"
/>
</odoo>

146
account_financial_report/wizard/journal_ledger_wizard.py

@ -1,133 +1,121 @@
# Copyright 2017 ACSONE SA/NV
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
from odoo import api, fields, models, _
from odoo import _, api, fields, models
class JournalLedgerReportWizard(models.TransientModel):
"""Journal Ledger report wizard."""
_name = 'journal.ledger.report.wizard'
_name = "journal.ledger.report.wizard"
_description = "Journal Ledger Report Wizard"
company_id = fields.Many2one(
comodel_name='res.company',
comodel_name="res.company",
default=lambda self: self.env.user.company_id,
string='Company',
string="Company",
required=False,
ondelete='cascade',
)
date_range_id = fields.Many2one(
comodel_name='date.range',
string='Date range',
)
date_from = fields.Date(
string="Start date",
required=True
)
date_to = fields.Date(
string="End date",
required=True
ondelete="cascade",
)
date_range_id = fields.Many2one(comodel_name="date.range", string="Date range",)
date_from = fields.Date(string="Start date", required=True)
date_to = fields.Date(string="End date", required=True)
journal_ids = fields.Many2many(
comodel_name='account.journal',
string="Journals",
required=False,
comodel_name="account.journal", string="Journals", required=False,
)
move_target = fields.Selection(
selection='_get_move_targets',
default='all',
required=True,
selection="_get_move_targets", default="all", required=True,
)
foreign_currency = fields.Boolean()
sort_option = fields.Selection(
selection='_get_sort_options',
selection="_get_sort_options",
string="Sort entries by",
default='move_name',
default="move_name",
required=True,
)
group_option = fields.Selection(
selection='_get_group_options',
selection="_get_group_options",
string="Group entries by",
default='journal',
default="journal",
required=True,
)
with_account_name = fields.Boolean(
default=False,
)
with_account_name = fields.Boolean(default=False,)
@api.model
def _get_move_targets(self):
return [
('all', _("All")),
('posted', _("Posted")),
('draft', _("Not Posted"))
]
return [("all", _("All")), ("posted", _("Posted")), ("draft", _("Not Posted"))]
@api.model
def _get_sort_options(self):
return [
('move_name', _("Entry number")),
('date', _("Date")),
("move_name", _("Entry number")),
("date", _("Date")),
]
@api.model
def _get_group_options(self):
return [
('journal', _("Journal")),
('none', _("No group")),
("journal", _("Journal")),
("none", _("No group")),
]
@api.onchange('date_range_id')
@api.onchange("date_range_id")
def onchange_date_range_id(self):
self.date_from = self.date_range_id.date_start
self.date_to = self.date_range_id.date_end
@api.onchange('company_id')
@api.onchange("company_id")
def onchange_company_id(self):
"""Handle company change."""
if self.company_id and self.date_range_id.company_id and \
self.date_range_id.company_id != self.company_id:
if (
self.company_id
and self.date_range_id.company_id
and self.date_range_id.company_id != self.company_id
):
self.date_range_id = False
if self.company_id and self.journal_ids:
self.journal_ids = self.journal_ids.filtered(
lambda p: p.company_id == self.company_id or not p.company_id)
res = {'domain': {'journal_ids': []}}
lambda p: p.company_id == self.company_id or not p.company_id
)
res = {"domain": {"journal_ids": []}}
if not self.company_id:
return res
else:
res['domain']['journal_ids'] += [
('company_id', '=', self.company_id.id)]
res["domain"]["journal_ids"] += [("company_id", "=", self.company_id.id)]
return res
@api.multi
def _print_report(self, report_type):
self.ensure_one()
data = self._prepare_report_journal_ledger()
if report_type == 'xlsx':
report_name = 'a_f_r.report_journal_ledger_xlsx'
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)
report_name = "account_financial_report.journal_ledger"
return (
self.env["ir.actions.report"]
.search(
[("report_name", "=", report_name), ("report_type", "=", report_type)],
limit=1,
)
.report_action(self, data=data)
)
@api.multi
def button_export_html(self):
self.ensure_one()
report_type = 'qweb-html'
report_type = "qweb-html"
return self._export(report_type)
@api.multi
def button_export_pdf(self):
report_type = 'qweb-pdf'
report_type = "qweb-pdf"
return self._export(report_type)
@api.multi
def button_export_xlsx(self):
self.ensure_one()
report_type = 'xlsx'
report_type = "xlsx"
return self._export(report_type)
@api.multi
@ -136,19 +124,20 @@ class JournalLedgerReportWizard(models.TransientModel):
journals = self.journal_ids
if not journals:
# Not selecting a journal means that we'll display all journals
journals = self.env['account.journal'].search(
[('company_id', '=', self.company_id.id)])
journals = self.env["account.journal"].search(
[("company_id", "=", self.company_id.id)]
)
return {
'wizard_id': self.id,
'date_from': self.date_from,
'date_to': self.date_to,
'move_target': self.move_target,
'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id,
'journal_ids': journals.ids,
'sort_option': self.sort_option,
'group_option': self.group_option,
'with_account_name': self.with_account_name,
"wizard_id": self.id,
"date_from": self.date_from,
"date_to": self.date_to,
"move_target": self.move_target,
"foreign_currency": self.foreign_currency,
"company_id": self.company_id.id,
"journal_ids": journals.ids,
"sort_option": self.sort_option,
"group_option": self.group_option,
"with_account_name": self.with_account_name,
}
def _export(self, report_type):
@ -158,26 +147,25 @@ class JournalLedgerReportWizard(models.TransientModel):
@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']
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)
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']
return partner_data[str(partner_id)]["name"]
else:
return ''
return ""
@api.model
def _get_atr_from_dict(self, obj_id, data, key):

82
account_financial_report/wizard/journal_ledger_wizard_view.xml

@ -1,66 +1,76 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2017 ACSONE SA/NV
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -->
<odoo>
<record id="journal_ledger_wizard" model="ir.ui.view">
<field name="name">Journal Ledger</field>
<field name="model">journal.ledger.report.wizard</field>
<field name="arch" type="xml">
<form>
<group>
<field name="company_id" groups="base.group_multi_company"/>
<field name="company_id" groups="base.group_multi_company" />
</group>
<separator string="Periods"/>
<separator string="Periods" />
<group>
<group>
<field name="date_range_id"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="date_range_id" />
<field name="date_from" />
<field name="date_to" />
</group>
<group/>
<group />
</group>
<separator string="Options"/>
<separator string="Options" />
<group name="options">
<group>
<field name="move_target" widget="radio" options="{'horizontal': true}"/>
<field name="sort_option"/>
<field name="group_option"/>
<field name="foreign_currency"/>
<field name="with_account_name"/>
<field
name="move_target"
widget="radio"
options="{'horizontal': true}"
/>
<field name="sort_option" />
<field name="group_option" />
<field name="foreign_currency" />
<field name="with_account_name" />
</group>
<group/>
<group />
</group>
<separator string="Journals"/>
<separator string="Journals" />
<group>
<field name="journal_ids" widget="many2many_tags"/>
<field name="journal_ids" widget="many2many_tags" />
</group>
<footer>
<button name="button_export_html" string="View"
type="object" default_focus="1" class="oe_highlight"/>
<button
name="button_export_html"
string="View"
type="object"
default_focus="1"
class="oe_highlight"
/>
or
<button name="button_export_pdf" string="Export PDF" type="object"/>
<button
name="button_export_pdf"
string="Export PDF"
type="object"
/>
or
<button name="button_export_xlsx" string="Export XLSX" type="object"/>
<button
name="button_export_xlsx"
string="Export XLSX"
type="object"
/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<act_window id="action_journal_ledger_wizard"
name="Journal Ledger"
res_model="journal.ledger.report.wizard"
view_type="form"
view_mode="form"
view_id="journal_ledger_wizard"
target="new" />
<act_window
id="action_journal_ledger_wizard"
name="Journal Ledger"
res_model="journal.ledger.report.wizard"
view_type="form"
view_mode="form"
view_id="journal_ledger_wizard"
target="new"
/>
</odoo>

130
account_financial_report/wizard/open_items_wizard.py

@ -3,7 +3,7 @@
# Copyright 2016 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
from odoo import models, fields, api
from odoo import api, fields, models
class OpenItemsReportWizard(models.TransientModel):
@ -11,134 +11,138 @@ class OpenItemsReportWizard(models.TransientModel):
_name = "open.items.report.wizard"
_description = "Open Items Report Wizard"
_inherit = 'account_financial_report_abstract_wizard'
_inherit = "account_financial_report_abstract_wizard"
company_id = fields.Many2one(
comodel_name='res.company',
comodel_name="res.company",
default=lambda self: self.env.user.company_id,
required=False,
string='Company'
string="Company",
)
date_at = fields.Date(required=True, default=fields.Date.context_today)
date_from = fields.Date(string="Date From")
target_move = fields.Selection(
[("posted", "All Posted Entries"), ("all", "All Entries")],
string="Target Moves",
required=True,
default="all",
)
date_at = fields.Date(required=True,
default=fields.Date.context_today)
date_from = fields.Date(string='Date From')
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')],
string='Target Moves',
required=True,
default='all')
account_ids = fields.Many2many(
comodel_name='account.account',
string='Filter accounts',
domain=[('reconcile', '=', True)],
comodel_name="account.account",
string="Filter accounts",
domain=[("reconcile", "=", True)],
)
hide_account_at_0 = fields.Boolean(
string='Hide account ending balance at 0', default=True,
help='Use this filter to hide an account or a partner '
'with an ending balance at 0. '
'If partners are filtered, '
'debits and credits totals will not match the trial balance.'
string="Hide account ending balance at 0",
default=True,
help="Use this filter to hide an account or a partner "
"with an ending balance at 0. "
"If partners are filtered, "
"debits and credits totals will not match the trial balance.",
)
receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean()
partner_ids = fields.Many2many(
comodel_name='res.partner',
string='Filter partners',
comodel_name="res.partner",
string="Filter partners",
default=lambda self: self._default_partners(),
)
foreign_currency = fields.Boolean(
string='Show foreign currency',
help='Display foreign currency for move lines, unless '
'account currency is not setup through chart of accounts '
'will display initial and final balance in that currency.',
string="Show foreign currency",
help="Display foreign currency for move lines, unless "
"account currency is not setup through chart of accounts "
"will display initial and final balance in that currency.",
default=lambda self: self._default_foreign_currency(),
)
def _default_foreign_currency(self):
return self.env.user.has_group('base.group_multi_currency')
return self.env.user.has_group("base.group_multi_currency")
@api.onchange('company_id')
@api.onchange("company_id")
def onchange_company_id(self):
"""Handle company change."""
if self.company_id and self.partner_ids:
self.partner_ids = self.partner_ids.filtered(
lambda p: p.company_id == self.company_id or
not p.company_id)
lambda p: p.company_id == self.company_id or not p.company_id
)
if self.company_id and self.account_ids:
if self.receivable_accounts_only or self.payable_accounts_only:
self.onchange_type_accounts_only()
else:
self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id)
res = {'domain': {'account_ids': [],
'partner_ids': []}}
lambda a: a.company_id == self.company_id
)
res = {"domain": {"account_ids": [], "partner_ids": []}}
if not self.company_id:
return res
else:
res['domain']['account_ids'] += [
('company_id', '=', self.company_id.id)]
res['domain']['partner_ids'] += self._get_partner_ids_domain()
res["domain"]["account_ids"] += [("company_id", "=", self.company_id.id)]
res["domain"]["partner_ids"] += self._get_partner_ids_domain()
return res
@api.onchange('receivable_accounts_only', 'payable_accounts_only')
@api.onchange("receivable_accounts_only", "payable_accounts_only")
def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change."""
domain = [('company_id', '=', self.company_id.id)]
domain = [("company_id", "=", self.company_id.id)]
if self.receivable_accounts_only or 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:
domain += [('internal_type', '=', 'receivable')]
domain += [("internal_type", "=", "receivable")]
elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')]
domain += [("internal_type", "=", "payable")]
elif not self.receivable_accounts_only and not self.payable_accounts_only:
domain += [('reconcile', '=', True)]
self.account_ids = self.env['account.account'].search(domain)
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'
if report_type == "xlsx":
report_name = "a_f_r.report_open_items_xlsx"
else:
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)
report_name = "account_financial_report.open_items"
return (
self.env["ir.actions.report"]
.search(
[("report_name", "=", report_name), ("report_type", "=", report_type)],
limit=1,
)
.report_action(self, data=data)
)
@api.multi
def button_export_html(self):
self.ensure_one()
report_type = 'qweb-html'
report_type = "qweb-html"
return self._export(report_type)
@api.multi
def button_export_pdf(self):
self.ensure_one()
report_type = 'qweb-pdf'
report_type = "qweb-pdf"
return self._export(report_type)
@api.multi
def button_export_xlsx(self):
self.ensure_one()
report_type = 'xlsx'
report_type = "xlsx"
return self._export(report_type)
def _prepare_report_open_items(self):
self.ensure_one()
return {
'wizard_id': self.id,
'date_at': fields.Date.to_string(self.date_at),
'date_from': self.date_from or False,
'only_posted_moves': self.target_move == 'posted',
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id,
'target_move': self.target_move,
'account_ids': self.account_ids.ids,
'partner_ids': self.partner_ids.ids or [],
"wizard_id": self.id,
"date_at": fields.Date.to_string(self.date_at),
"date_from": self.date_from or False,
"only_posted_moves": self.target_move == "posted",
"hide_account_at_0": self.hide_account_at_0,
"foreign_currency": self.foreign_currency,
"company_id": self.company_id.id,
"target_move": self.target_move,
"account_ids": self.account_ids.ids,
"partner_ids": self.partner_ids.ids or [],
}
def _export(self, report_type):

107
account_financial_report/wizard/open_items_wizard_view.xml

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- OPEN ITEMS -->
<record id="open_items_wizard" model="ir.ui.view">
<field name="name">Open Items</field>
@ -8,69 +7,91 @@
<field name="arch" type="xml">
<form>
<group name="main_info">
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field
name="company_id"
options="{'no_create': True}"
groups="base.group_multi_company"
/>
</group>
<group name="filters">
<group name="date_range">
<field name="date_at"/>
<field name="date_from"/>
<field name="date_at" />
<field name="date_from" />
</group>
<group name="other_filters">
<field name="target_move" widget="radio"/>
<field name="hide_account_at_0"/>
<field name="foreign_currency"/>
<field name="target_move" widget="radio" />
<field name="hide_account_at_0" />
<field name="foreign_currency" />
</group>
</group>
<group name="partner_filter" col="1">
<label for="partner_ids"/>
<field name="partner_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"/>
<label for="partner_ids" />
<field
name="partner_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
/>
</group>
<group name="account_filter" col="4">
<field name="receivable_accounts_only"/>
<field name="payable_accounts_only"/>
<field name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
colspan="4"/>
<field name="receivable_accounts_only" />
<field name="payable_accounts_only" />
<field
name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
colspan="4"
/>
</group>
<footer>
<button name="button_export_html" string="View"
type="object" default_focus="1" class="oe_highlight"/>
<button
name="button_export_html"
string="View"
type="object"
default_focus="1"
class="oe_highlight"
/>
or
<button name="button_export_pdf" string="Export PDF" type="object"/>
<button
name="button_export_pdf"
string="Export PDF"
type="object"
/>
or
<button name="button_export_xlsx" string="Export XLSX" type="object"/>
<button
name="button_export_xlsx"
string="Export XLSX"
type="object"
/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</field>
</record>
<act_window id="action_open_items_wizard"
name="Open Items"
res_model="open.items.report.wizard"
view_type="form"
view_mode="form"
view_id="open_items_wizard"
target="new" />
<act_window
id="action_open_items_wizard"
name="Open Items"
res_model="open.items.report.wizard"
view_type="form"
view_mode="form"
view_id="open_items_wizard"
target="new"
/>
<!--Add to res.partner action-->
<act_window id="act_action_open_items_wizard_partner_relation"
name="Open Items Partner"
res_model="open.items.report.wizard"
src_model="res.partner"
view_mode="form"
context="{
<act_window
id="act_action_open_items_wizard_partner_relation"
name="Open Items Partner"
res_model="open.items.report.wizard"
src_model="res.partner"
view_mode="form"
context="{
'default_receivable_accounts_only':1,
'default_payable_accounts_only':1,
}"
groups="account.group_account_manager"
key2="client_action_multi"
target="new" />
groups="account.group_account_manager"
key2="client_action_multi"
target="new"
/>
</odoo>

264
account_financial_report/wizard/trial_balance_wizard.py

@ -4,7 +4,7 @@
# Copyright 2018 Eficent Business and IT Consuting Services, S.L.
# 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.exceptions import UserError, ValidationError
@ -13,246 +13,260 @@ class TrialBalanceReportWizard(models.TransientModel):
_name = "trial.balance.report.wizard"
_description = "Trial Balance Report Wizard"
_inherit = 'account_financial_report_abstract_wizard'
_inherit = "account_financial_report_abstract_wizard"
company_id = fields.Many2one(
comodel_name='res.company',
comodel_name="res.company",
default=lambda self: self.env.user.company_id,
required=False,
string='Company'
)
date_range_id = fields.Many2one(
comodel_name='date.range',
string='Date range'
string="Company",
)
date_range_id = fields.Many2one(comodel_name="date.range", string="Date range")
date_from = fields.Date(required=True)
date_to = fields.Date(required=True)
fy_start_date = fields.Date(compute='_compute_fy_start_date')
target_move = fields.Selection([('posted', 'All Posted Entries'),
('all', 'All Entries')],
string='Target Moves',
required=True,
default='all')
fy_start_date = fields.Date(compute="_compute_fy_start_date")
target_move = fields.Selection(
[("posted", "All Posted Entries"), ("all", "All Entries")],
string="Target Moves",
required=True,
default="all",
)
hierarchy_on = fields.Selection(
[('computed', 'Computed Accounts'),
('relation', 'Child Accounts'),
('none', 'No hierarchy')],
string='Hierarchy On',
[
("computed", "Computed Accounts"),
("relation", "Child Accounts"),
("none", "No hierarchy"),
],
string="Hierarchy On",
required=True,
default='none',
default="none",
help="""Computed Accounts: Use when the account group have codes
that represent prefixes of the actual accounts.\n
Child Accounts: Use when your account groups are hierarchical.\n
No hierarchy: Use to display just the accounts, without any grouping.
""",
)
limit_hierarchy_level = fields.Boolean('Limit hierarchy levels')
show_hierarchy_level = fields.Integer('Hierarchy Levels to display',
default=1)
limit_hierarchy_level = fields.Boolean("Limit hierarchy levels")
show_hierarchy_level = fields.Integer("Hierarchy Levels to display", default=1)
hide_parent_hierarchy_level = fields.Boolean(
'Do not display parent levels', default=False)
"Do not display parent levels", default=False
)
account_ids = fields.Many2many(
comodel_name='account.account',
string='Filter accounts',
comodel_name="account.account", string="Filter accounts",
)
hide_account_at_0 = fields.Boolean(
string='Hide accounts at 0', default=True,
help='When this option is enabled, the trial balance will '
'not display accounts that have initial balance = '
'debit = credit = end balance = 0',
string="Hide accounts at 0",
default=True,
help="When this option is enabled, the trial balance will "
"not display accounts that have initial balance = "
"debit = credit = end balance = 0",
)
receivable_accounts_only = fields.Boolean()
payable_accounts_only = fields.Boolean()
show_partner_details = fields.Boolean()
partner_ids = fields.Many2many(
comodel_name='res.partner',
string='Filter partners',
)
journal_ids = fields.Many2many(
comodel_name="account.journal",
comodel_name="res.partner", string="Filter partners",
)
journal_ids = fields.Many2many(comodel_name="account.journal",)
not_only_one_unaffected_earnings_account = fields.Boolean(
readonly=True,
string='Not only one unaffected earnings account'
readonly=True, string="Not only one unaffected earnings account"
)
foreign_currency = fields.Boolean(
string='Show foreign currency',
help='Display foreign currency for move lines, unless '
'account currency is not setup through chart of accounts '
'will display initial and final balance in that currency.'
string="Show foreign currency",
help="Display foreign currency for move lines, unless "
"account currency is not setup through chart of accounts "
"will display initial and final balance in that currency.",
)
@api.multi
@api.constrains('hierarchy_on', 'show_hierarchy_level')
@api.constrains("hierarchy_on", "show_hierarchy_level")
def _check_show_hierarchy_level(self):
for rec in self:
if rec.hierarchy_on != 'none' and rec.show_hierarchy_level <= 0:
raise UserError(_('The hierarchy level to filter on must be '
'greater than 0.'))
if rec.hierarchy_on != "none" and rec.show_hierarchy_level <= 0:
raise UserError(
_("The hierarchy level to filter on must be " "greater than 0.")
)
@api.depends('date_from')
@api.depends("date_from")
def _compute_fy_start_date(self):
for wiz in self.filtered('date_from'):
for wiz in self.filtered("date_from"):
date = fields.Datetime.from_string(wiz.date_from)
res = self.company_id.compute_fiscalyear_dates(date)
wiz.fy_start_date = fields.Date.to_string(res['date_from'])
wiz.fy_start_date = fields.Date.to_string(res["date_from"])
@api.onchange('company_id')
@api.onchange("company_id")
def onchange_company_id(self):
"""Handle company change."""
account_type = self.env.ref('account.data_unaffected_earnings')
count = self.env['account.account'].search_count(
account_type = self.env.ref("account.data_unaffected_earnings")
count = self.env["account.account"].search_count(
[
('user_type_id', '=', account_type.id),
('company_id', '=', self.company_id.id)
])
("user_type_id", "=", account_type.id),
("company_id", "=", self.company_id.id),
]
)
self.not_only_one_unaffected_earnings_account = count != 1
if self.company_id and self.date_range_id.company_id and \
self.date_range_id.company_id != self.company_id:
if (
self.company_id
and self.date_range_id.company_id
and self.date_range_id.company_id != self.company_id
):
self.date_range_id = False
if self.company_id and self.partner_ids:
self.partner_ids = self.partner_ids.filtered(
lambda p: p.company_id == self.company_id or
not p.company_id)
lambda p: p.company_id == self.company_id or not p.company_id
)
if self.company_id and self.journal_ids:
self.journal_ids = self.journal_ids.filtered(
lambda a: a.company_id == self.company_id)
lambda a: a.company_id == self.company_id
)
if self.company_id and self.account_ids:
if self.receivable_accounts_only or self.payable_accounts_only:
self.onchange_type_accounts_only()
else:
self.account_ids = self.account_ids.filtered(
lambda a: a.company_id == self.company_id)
res = {'domain': {'account_ids': [],
'partner_ids': [],
'date_range_id': [],
'journal_ids': [],
}
}
lambda a: a.company_id == self.company_id
)
res = {
"domain": {
"account_ids": [],
"partner_ids": [],
"date_range_id": [],
"journal_ids": [],
}
}
if not self.company_id:
return res
else:
res['domain']['account_ids'] += [
('company_id', '=', self.company_id.id)]
res['domain']['partner_ids'] += self._get_partner_ids_domain()
res['domain']['date_range_id'] += [
'|', ('company_id', '=', self.company_id.id),
('company_id', '=', False)]
res['domain']['journal_ids'] += [
('company_id', '=', self.company_id.id)]
res["domain"]["account_ids"] += [("company_id", "=", self.company_id.id)]
res["domain"]["partner_ids"] += self._get_partner_ids_domain()
res["domain"]["date_range_id"] += [
"|",
("company_id", "=", self.company_id.id),
("company_id", "=", False),
]
res["domain"]["journal_ids"] += [("company_id", "=", self.company_id.id)]
return res
@api.onchange('date_range_id')
@api.onchange("date_range_id")
def onchange_date_range_id(self):
"""Handle date range change."""
self.date_from = self.date_range_id.date_start
self.date_to = self.date_range_id.date_end
@api.multi
@api.constrains('company_id', 'date_range_id')
@api.constrains("company_id", "date_range_id")
def _check_company_id_date_range_id(self):
for rec in self.sudo():
if rec.company_id and rec.date_range_id.company_id and\
rec.company_id != rec.date_range_id.company_id:
if (
rec.company_id
and rec.date_range_id.company_id
and rec.company_id != rec.date_range_id.company_id
):
raise ValidationError(
_('The Company in the Trial Balance Report Wizard and in '
'Date Range must be the same.'))
_(
"The Company in the Trial Balance Report Wizard and in "
"Date Range must be the same."
)
)
@api.onchange('receivable_accounts_only', 'payable_accounts_only')
@api.onchange("receivable_accounts_only", "payable_accounts_only")
def onchange_type_accounts_only(self):
"""Handle receivable/payable accounts only change."""
if self.receivable_accounts_only or self.payable_accounts_only:
domain = [('company_id', '=', self.company_id.id)]
domain = [("company_id", "=", self.company_id.id)]
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:
domain += [('internal_type', '=', 'receivable')]
domain += [("internal_type", "=", "receivable")]
elif self.payable_accounts_only:
domain += [('internal_type', '=', 'payable')]
self.account_ids = self.env['account.account'].search(domain)
domain += [("internal_type", "=", "payable")]
self.account_ids = self.env["account.account"].search(domain)
else:
self.account_ids = None
@api.onchange('show_partner_details')
@api.onchange("show_partner_details")
def onchange_show_partner_details(self):
"""Handle partners change."""
if self.show_partner_details:
self.receivable_accounts_only = self.payable_accounts_only = True
else:
self.receivable_accounts_only = self.\
payable_accounts_only = False
self.receivable_accounts_only = self.payable_accounts_only = False
@api.multi
@api.depends('company_id')
@api.depends("company_id")
def _compute_unaffected_earnings_account(self):
account_type = self.env.ref('account.data_unaffected_earnings')
account_type = self.env.ref("account.data_unaffected_earnings")
for record in self:
record.unaffected_earnings_account = self.env[
'account.account'].search(
record.unaffected_earnings_account = self.env["account.account"].search(
[
('user_type_id', '=', account_type.id),
('company_id', '=', record.company_id.id)
])
("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
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'
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)
report_name = "account_financial_report.trial_balance"
return (
self.env["ir.actions.report"]
.search(
[("report_name", "=", report_name), ("report_type", "=", report_type)],
limit=1,
)
.report_action(self, data=data)
)
@api.multi
def button_export_html(self):
self.ensure_one()
report_type = 'qweb-html'
report_type = "qweb-html"
return self._export(report_type)
@api.multi
def button_export_pdf(self):
self.ensure_one()
report_type = 'qweb-pdf'
report_type = "qweb-pdf"
return self._export(report_type)
@api.multi
def button_export_xlsx(self):
self.ensure_one()
report_type = 'xlsx'
report_type = "xlsx"
return self._export(report_type)
def _prepare_report_trial_balance(self):
self.ensure_one()
return {
'wizard_id': self.id,
'date_from': self.date_from,
'date_to': self.date_to,
'only_posted_moves': self.target_move == 'posted',
'hide_account_at_0': self.hide_account_at_0,
'foreign_currency': self.foreign_currency,
'company_id': self.company_id.id,
'account_ids': self.account_ids.ids or [],
'partner_ids': self.partner_ids.ids or [],
'journal_ids': self.journal_ids.ids or [],
'fy_start_date': self.fy_start_date,
'hierarchy_on': self.hierarchy_on,
'limit_hierarchy_level': self.limit_hierarchy_level,
'show_hierarchy_level': self.show_hierarchy_level,
'hide_parent_hierarchy_level': self.hide_parent_hierarchy_level,
'show_partner_details': self.show_partner_details,
'unaffected_earnings_account': self.unaffected_earnings_account.id,
"wizard_id": self.id,
"date_from": self.date_from,
"date_to": self.date_to,
"only_posted_moves": self.target_move == "posted",
"hide_account_at_0": self.hide_account_at_0,
"foreign_currency": self.foreign_currency,
"company_id": self.company_id.id,
"account_ids": self.account_ids.ids or [],
"partner_ids": self.partner_ids.ids or [],
"journal_ids": self.journal_ids.ids or [],
"fy_start_date": self.fy_start_date,
"hierarchy_on": self.hierarchy_on,
"limit_hierarchy_level": self.limit_hierarchy_level,
"show_hierarchy_level": self.show_hierarchy_level,
"hide_parent_hierarchy_level": self.hide_parent_hierarchy_level,
"show_partner_details": self.show_partner_details,
"unaffected_earnings_account": self.unaffected_earnings_account.id,
}
def _export(self, report_type):

164
account_financial_report/wizard/trial_balance_wizard_view.xml

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<!-- TRIAL BALANCE -->
<record id="trial_balance_wizard" model="ir.ui.view">
<field name="name">Trial Balance</field>
@ -8,84 +7,135 @@
<field name="arch" type="xml">
<form>
<group name="main_info">
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field
name="company_id"
options="{'no_create': True}"
groups="base.group_multi_company"
/>
</group>
<div attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', True)]}">
<div
attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', True)]}"
>
<group name="filters">
<group name="date_range">
<field name="date_range_id"/>
<field name="date_from"/>
<field name="date_to"/>
<field name="fy_start_date" invisible="1"/>
<field name="date_range_id" />
<field name="date_from" />
<field name="date_to" />
<field name="fy_start_date" invisible="1" />
</group>
<group name="other_filters">
<field name="target_move" widget="radio"/>
<field name="hide_account_at_0"/>
<field name="show_partner_details"/>
<field name="hierarchy_on" widget="radio" attrs="{'invisible':[('show_partner_details','=',True)]}"/>
<field name="limit_hierarchy_level" attrs="{'invisible':['|', ('hierarchy_on','in',['none', 'computed']),('show_partner_details','=',True)]}"/>
<field name="show_hierarchy_level" attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"/>
<field name="hide_parent_hierarchy_level" attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"/>
<field name="foreign_currency"/>
<field name="target_move" widget="radio" />
<field name="hide_account_at_0" />
<field name="show_partner_details" />
<field
name="hierarchy_on"
widget="radio"
attrs="{'invisible':[('show_partner_details','=',True)]}"
/>
<field
name="limit_hierarchy_level"
attrs="{'invisible':['|', ('hierarchy_on','in',['none', 'computed']),('show_partner_details','=',True)]}"
/>
<field
name="show_hierarchy_level"
attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"
/>
<field
name="hide_parent_hierarchy_level"
attrs="{'invisible':[('limit_hierarchy_level','=', False)]}"
/>
<field name="foreign_currency" />
</group>
</group>
<group name="partner_filter" attrs="{'invisible':[('show_partner_details','!=',True)]}" col="1">
<label for="partner_ids"/>
<field name="partner_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"/>
<group
name="partner_filter"
attrs="{'invisible':[('show_partner_details','!=',True)]}"
col="1"
>
<label for="partner_ids" />
<field
name="partner_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
/>
</group>
<label for="journal_ids"/>
<field name="journal_ids"
widget="many2many_tags"
nolabel="1"
options="{'no_create': True}"
<label for="journal_ids" />
<field
name="journal_ids"
widget="many2many_tags"
nolabel="1"
options="{'no_create': True}"
/>
<group attrs="{'invisible':[('show_partner_details','!=',True)]}"/>
<div/>
<group attrs="{'invisible':[('show_partner_details','!=',True)]}" />
<div />
<group name="account_filter" col="4">
<label for="account_ids" colspan="4"/>
<field name="receivable_accounts_only"/>
<field name="payable_accounts_only"/>
<field name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
colspan="4"/>
<label for="account_ids" colspan="4" />
<field name="receivable_accounts_only" />
<field name="payable_accounts_only" />
<field
name="account_ids"
nolabel="1"
widget="many2many_tags"
options="{'no_create': True}"
colspan="4"
/>
</group>
</div>
<div attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', False)]}">
<field name="not_only_one_unaffected_earnings_account" invisible="1"/>
<group/>
<h4>Trial Balance can be computed only if selected company have only one unaffected earnings account.</h4>
<group/>
<div
attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', False)]}"
>
<field
name="not_only_one_unaffected_earnings_account"
invisible="1"
/>
<group />
<h4
>Trial Balance can be computed only if selected company have only one unaffected earnings account.</h4>
<group />
</div>
<footer>
<div attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', True)]}">
<button name="button_export_html" string="View"
type="object" default_focus="1" class="oe_highlight"/>
<div
attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', True)]}"
>
<button
name="button_export_html"
string="View"
type="object"
default_focus="1"
class="oe_highlight"
/>
or
<button name="button_export_pdf" string="Export PDF" type="object"/>
<button
name="button_export_pdf"
string="Export PDF"
type="object"
/>
or
<button name="button_export_xlsx" string="Export XLSX" type="object"/>
<button
name="button_export_xlsx"
string="Export XLSX"
type="object"
/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</div>
<div attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', False)]}">
<div
attrs="{'invisible': [('not_only_one_unaffected_earnings_account', '=', False)]}"
>
<button string="Cancel" class="oe_link" special="cancel" />
</div>
</footer>
</form>
</field>
</record>
<act_window id="action_trial_balance_wizard"
name="Trial Balance"
res_model="trial.balance.report.wizard"
view_type="form"
view_mode="form"
view_id="trial_balance_wizard"
target="new" />
<act_window
id="action_trial_balance_wizard"
name="Trial Balance"
res_model="trial.balance.report.wizard"
view_type="form"
view_mode="form"
view_id="trial_balance_wizard"
target="new"
/>
</odoo>

101
account_financial_report/wizard/vat_report_wizard.py

@ -1,7 +1,7 @@
# Copyright 2018 Forest and Biomass Romania
# 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.exceptions import ValidationError
@ -10,96 +10,107 @@ class VATReportWizard(models.TransientModel):
_description = "VAT Report Wizard"
company_id = fields.Many2one(
comodel_name='res.company',
comodel_name="res.company",
default=lambda self: self.env.user.company_id,
required=False,
string='Company'
string="Company",
)
date_range_id = fields.Many2one(
comodel_name='date.range',
string='Date range'
date_range_id = fields.Many2one(comodel_name="date.range", string="Date range")
date_from = fields.Date("Start Date", required=True)
date_to = fields.Date("End Date", required=True)
based_on = fields.Selection(
[("taxtags", "Tax Tags"), ("taxgroups", "Tax Groups")],
string="Based On",
required=True,
default="taxtags",
)
date_from = fields.Date('Start Date', required=True)
date_to = fields.Date('End Date', required=True)
based_on = fields.Selection([('taxtags', 'Tax Tags'),
('taxgroups', 'Tax Groups')],
string='Based On',
required=True,
default='taxtags')
tax_detail = fields.Boolean('Detail Taxes')
tax_detail = fields.Boolean("Detail Taxes")
@api.onchange('company_id')
@api.onchange("company_id")
def onchange_company_id(self):
if self.company_id and self.date_range_id.company_id and \
self.date_range_id.company_id != self.company_id:
if (
self.company_id
and self.date_range_id.company_id
and self.date_range_id.company_id != self.company_id
):
self.date_range_id = False
res = {'domain': {'date_range_id': [],
}
}
res = {"domain": {"date_range_id": [],}}
if not self.company_id:
return res
else:
res['domain']['date_range_id'] += [
'|', ('company_id', '=', self.company_id.id),
('company_id', '=', False)]
res["domain"]["date_range_id"] += [
"|",
("company_id", "=", self.company_id.id),
("company_id", "=", False),
]
return res
@api.onchange('date_range_id')
@api.onchange("date_range_id")
def onchange_date_range_id(self):
"""Handle date range change."""
self.date_from = self.date_range_id.date_start
self.date_to = self.date_range_id.date_end
@api.multi
@api.constrains('company_id', 'date_range_id')
@api.constrains("company_id", "date_range_id")
def _check_company_id_date_range_id(self):
for rec in self.sudo():
if rec.company_id and rec.date_range_id.company_id and\
rec.company_id != rec.date_range_id.company_id:
if (
rec.company_id
and rec.date_range_id.company_id
and rec.company_id != rec.date_range_id.company_id
):
raise ValidationError(
_('The Company in the Vat Report Wizard and in '
'Date Range must be the same.'))
_(
"The Company in the Vat Report Wizard and in "
"Date Range must be the same."
)
)
@api.multi
def _print_report(self, report_type):
self.ensure_one()
data = self._prepare_vat_report()
if report_type == 'xlsx':
report_name = 'a_f_r.report_vat_report_xlsx'
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)
report_name = "account_financial_report.vat_report"
return (
self.env["ir.actions.report"]
.search(
[("report_name", "=", report_name), ("report_type", "=", report_type)],
limit=1,
)
.report_action(self, data=data)
)
@api.multi
def button_export_html(self):
self.ensure_one()
report_type = 'qweb-html'
report_type = "qweb-html"
return self._export(report_type)
@api.multi
def button_export_pdf(self):
self.ensure_one()
report_type = 'qweb-pdf'
report_type = "qweb-pdf"
return self._export(report_type)
@api.multi
def button_export_xlsx(self):
self.ensure_one()
report_type = 'xlsx'
report_type = "xlsx"
return self._export(report_type)
def _prepare_vat_report(self):
self.ensure_one()
return {
'wizard_id': self.id,
'company_id': self.company_id.id,
'date_from': self.date_from,
'date_to': self.date_to,
'based_on': self.based_on,
'tax_detail': self.tax_detail,
"wizard_id": self.id,
"company_id": self.company_id.id,
"date_from": self.date_from,
"date_to": self.date_to,
"based_on": self.based_on,
"tax_detail": self.tax_detail,
}
def _export(self, report_type):

75
account_financial_report/wizard/vat_report_wizard_view.xml

@ -1,44 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8" ?>
<odoo>
<record id="vat_report_wizard" model="ir.ui.view">
<field name="name">vat_report_wizard_view</field>
<field name="model">vat.report.wizard</field>
<field name="arch" type="xml">
<form string="VAT Report Options">
<group name="main_info">
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
</group>
<group name="filters">
<group name="date_range">
<field name="date_range_id"/>
<field name="date_from"/>
<field name="date_to"/>
<form string="VAT Report Options">
<group name="main_info">
<field
name="company_id"
options="{'no_create': True}"
groups="base.group_multi_company"
/>
</group>
<group name="other_filters">
<field name="based_on" widget="radio"/>
<field name="tax_detail"/>
<group name="filters">
<group name="date_range">
<field name="date_range_id" />
<field name="date_from" />
<field name="date_to" />
</group>
<group name="other_filters">
<field name="based_on" widget="radio" />
<field name="tax_detail" />
</group>
</group>
</group>
<footer>
<button name="button_export_html" string="View"
type="object" default_focus="1" class="oe_highlight"/>
<footer>
<button
name="button_export_html"
string="View"
type="object"
default_focus="1"
class="oe_highlight"
/>
or
<button name="button_export_pdf" string="Export PDF" type="object"/>
<button
name="button_export_pdf"
string="Export PDF"
type="object"
/>
or
<button name="button_export_xlsx" string="Export XLSX" type="object"/>
<button
name="button_export_xlsx"
string="Export XLSX"
type="object"
/>
or
<button string="Cancel" class="oe_link" special="cancel" />
</footer>
</form>
</form>
</field>
</record>
<act_window id="action_vat_report_wizard"
name="VAT Report"
res_model="vat.report.wizard"
view_type="form"
view_mode="form"
view_id="vat_report_wizard"
target="new" />
<act_window
id="action_vat_report_wizard"
name="VAT Report"
res_model="vat.report.wizard"
view_type="form"
view_mode="form"
view_id="vat_report_wizard"
target="new"
/>
</odoo>
Loading…
Cancel
Save