From 037ac4f515b0ab52bcc2f5754d0bf7f017b25f98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Marques?= Date: Mon, 25 Jan 2021 15:43:26 +0000 Subject: [PATCH] [MIG] account_financial_report: Migration to 14.0 Since v14, Odoo defines the `__slots__` attribute in the `BaseModel` class (https://github.com/odoo/odoo/commit/ea3e39506a2b360545ec0cd1d3235e69ad16ea6c) This makes it impossible to add attributes to an instance like it was done here in v13. The use of the `report_data` dictionary passed between method is the closes and simples solution to this "issue". TT26415 Co-authored-by: Alex Cuellar --- account_financial_report/README.rst | 11 +- account_financial_report/__manifest__.py | 6 +- account_financial_report/models/__init__.py | 2 +- .../models/account_group.py | 12 +- .../readme/CONTRIBUTORS.rst | 1 + .../report/abstract_report_xlsx.py | 537 ++++++++++-------- .../report/aged_partner_balance_xlsx.py | 72 ++- .../report/general_ledger_xlsx.py | 42 +- .../report/journal_ledger_xlsx.py | 71 ++- .../report/open_items_xlsx.py | 39 +- .../report/trial_balance.py | 10 +- .../report/trial_balance_xlsx.py | 72 ++- account_financial_report/report/vat_report.py | 1 - .../report/vat_report_xlsx.py | 9 +- account_financial_report/reports.xml | 199 +++---- .../security/ir.model.access.csv | 7 + .../static/description/index.html | 9 +- .../tests/test_general_ledger.py | 2 +- .../tests/test_journal_ledger.py | 48 +- .../tests/test_trial_balance.py | 29 +- .../tests/test_vat_report.py | 8 +- .../aged_partner_balance_wizard_view.xml | 15 +- .../wizard/general_ledger_wizard.py | 9 +- .../wizard/general_ledger_wizard_view.xml | 45 +- .../wizard/journal_ledger_wizard_view.xml | 15 +- .../wizard/open_items_wizard_view.xml | 45 +- .../wizard/trial_balance_wizard.py | 9 +- .../wizard/trial_balance_wizard_view.xml | 15 +- .../wizard/vat_report_wizard_view.xml | 15 +- oca_dependencies.txt | 2 + 30 files changed, 731 insertions(+), 626 deletions(-) create mode 100644 account_financial_report/security/ir.model.access.csv diff --git a/account_financial_report/README.rst b/account_financial_report/README.rst index 63c23766..a5a216f6 100644 --- a/account_financial_report/README.rst +++ b/account_financial_report/README.rst @@ -14,13 +14,13 @@ Account Financial Reports :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Faccount--financial--reporting-lightgray.png?logo=github - :target: https://github.com/OCA/account-financial-reporting/tree/13.0/account_financial_report + :target: https://github.com/OCA/account-financial-reporting/tree/14.0/account_financial_report :alt: OCA/account-financial-reporting .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/account-financial-reporting-13-0/account-financial-reporting-13-0-account_financial_report + :target: https://translation.odoo-community.org/projects/account-financial-reporting-14-0/account-financial-reporting-14-0-account_financial_report :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/91/13.0 + :target: https://runbot.odoo-community.org/runbot/91/14.0 :alt: Try me on Runbot |badge1| |badge2| |badge3| |badge4| |badge5| @@ -87,7 +87,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -128,6 +128,7 @@ Contributors * Pedro M. Baeza * Sergio Teruel * Ernesto Tejeda + * João Marques Much of the work in this module was done at a sprint in Sorrento, Italy in April 2016. @@ -145,6 +146,6 @@ OCA, or the Odoo Community Association, is a nonprofit organization whose mission is to support the collaborative development of Odoo features and promote its widespread use. -This module is part of the `OCA/account-financial-reporting `_ project on GitHub. +This module is part of the `OCA/account-financial-reporting `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/account_financial_report/__manifest__.py b/account_financial_report/__manifest__.py index 46fdc645..92639ca0 100644 --- a/account_financial_report/__manifest__.py +++ b/account_financial_report/__manifest__.py @@ -2,10 +2,11 @@ # Author: Julien Coux # Copyright 2016 Camptocamp SA # Copyright 2020 ForgeFlow S.L. (https://www.forgeflow.com) +# Copyright 2021 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). { "name": "Account Financial Reports", - "version": "13.0.1.4.1", + "version": "14.0.1.0.0", "category": "Reporting", "summary": "OCA Financial Reports", "author": "Camptocamp SA," @@ -13,9 +14,10 @@ "redCOR AG," "ForgeFlow," "Odoo Community Association (OCA)", - "website": "https://odoo-community.org/", + "website": "https://github.com/OCA/account-financial-reporting", "depends": ["account", "date_range", "report_xlsx"], "data": [ + "security/ir.model.access.csv", "wizard/aged_partner_balance_wizard_view.xml", "wizard/general_ledger_wizard_view.xml", "wizard/journal_ledger_wizard_view.xml", diff --git a/account_financial_report/models/__init__.py b/account_financial_report/models/__init__.py index 789507c9..afbe6974 100644 --- a/account_financial_report/models/__init__.py +++ b/account_financial_report/models/__init__.py @@ -1,4 +1,4 @@ -from . import account from . import account_group +from . import account from . import account_move_line from . import ir_actions_report diff --git a/account_financial_report/models/account_group.py b/account_financial_report/models/account_group.py index f1d237f0..dad94350 100644 --- a/account_financial_report/models/account_group.py +++ b/account_financial_report/models/account_group.py @@ -10,7 +10,7 @@ class AccountGroup(models.Model): 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) + level = fields.Integer(string="Level", compute="_compute_level") account_ids = fields.One2many( comodel_name="account.account", inverse_name="group_id", string="Accounts" ) @@ -31,15 +31,15 @@ class AccountGroup(models.Model): else: self.complete_name = self.name - @api.depends("code_prefix", "parent_id.complete_code") + @api.depends("code_prefix_start", "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 = "{}/{}".format( - self.parent_id.complete_code, self.code_prefix + self.parent_id.complete_code, self.code_prefix_start ) else: - self.complete_code = self.code_prefix + self.complete_code = self.code_prefix_start @api.depends("parent_id", "parent_id.level") def _compute_level(self): @@ -50,7 +50,7 @@ class AccountGroup(models.Model): group.level = group.parent_id.level + 1 @api.depends( - "code_prefix", + "code_prefix_start", "account_ids", "account_ids.code", "group_child_ids", @@ -60,6 +60,6 @@ class AccountGroup(models.Model): 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 + prefix = group.code_prefix_start if group.code_prefix_start else group.name gr_acc = accounts.filtered(lambda a: a.code.startswith(prefix)).ids group.compute_account_ids = [(6, 0, gr_acc)] diff --git a/account_financial_report/readme/CONTRIBUTORS.rst b/account_financial_report/readme/CONTRIBUTORS.rst index 484bb7fb..01623285 100644 --- a/account_financial_report/readme/CONTRIBUTORS.rst +++ b/account_financial_report/readme/CONTRIBUTORS.rst @@ -21,6 +21,7 @@ * Pedro M. Baeza * Sergio Teruel * Ernesto Tejeda + * João Marques Much of the work in this module was done at a sprint in Sorrento, Italy in April 2016. diff --git a/account_financial_report/report/abstract_report_xlsx.py b/account_financial_report/report/abstract_report_xlsx.py index 842f9a49..eaf2ebe8 100644 --- a/account_financial_report/report/abstract_report_xlsx.py +++ b/account_financial_report/report/abstract_report_xlsx.py @@ -1,5 +1,6 @@ # Author: Julien Coux # Copyright 2016 Camptocamp SA +# Copyright 2021 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import models @@ -9,56 +10,37 @@ class AbstractReportXslx(models.AbstractModel): _description = "Abstract XLSX Account Financial Report" _inherit = "report.report_xlsx.abstract" - def __init__(self, pool, cr): - # main sheet which will contains report - self.sheet = None - - # columns of the report - self.columns = None - - # row_pos must be incremented at each writing lines - self.row_pos = None - - # Formats - self.format_right = None - self.format_left = None - self.format_right_bold_italic = None - self.format_bold = None - self.format_header_left = None - self.format_header_center = None - self.format_header_right = None - self.format_header_amount = None - self.format_amount = None - self.format_percent_bold_italic = None - def get_workbook_options(self): - return {"constant_memory": True} + vals = super().get_workbook_options() + vals.update({"constant_memory": True}) + return vals def generate_xlsx_report(self, workbook, data, objects): - report = objects - - self.row_pos = 0 - - self._define_formats(workbook) - - report_name = self._get_report_name(report, data=data) + # Initialize report variables + report_data = { + "workbook": None, + "sheet": None, # main sheet which will contains report + "columns": None, # columns of the report + "row_pos": None, # row_pos must be incremented at each writing lines + "formats": None, + } + self._define_formats(workbook, report_data) + # Get report data + report_name = self._get_report_name(objects, data=data) report_footer = self._get_report_footer() - filters = self._get_report_filters(report) - self.columns = self._get_report_columns(report) - self.workbook = workbook - self.sheet = workbook.add_worksheet(report_name[:31]) - - self._set_column_width() - - self._write_report_title(report_name) - - self._write_filters(filters) - - self._generate_report_content(workbook, report, data) - - self._write_report_footer(report_footer) - - def _define_formats(self, workbook): + filters = self._get_report_filters(objects) + report_data["columns"] = self._get_report_columns(objects) + report_data["workbook"] = workbook + report_data["sheet"] = workbook.add_worksheet(report_name[:31]) + self._set_column_width(report_data) + # Fill report + report_data["row_pos"] = 0 + self._write_report_title(report_name, report_data) + self._write_filters(filters, report_data) + self._generate_report_content(workbook, objects, data, report_data) + self._write_report_footer(report_footer, report_data) + + def _define_formats(self, workbook, report_data): """Add cell formats to current workbook. Those formats can be used on all cell. Available formats are : @@ -72,77 +54,75 @@ 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_right_bold_italic = workbook.add_format( - {"align": "right", "bold": True, "italic": True} - ) - self.format_header_left = workbook.add_format( - {"bold": True, "border": True, "bg_color": "#FFFFCC"} - ) - self.format_header_center = workbook.add_format( - {"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"} - ) - self.format_header_amount = workbook.add_format( - {"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 - ) - 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_bold.set_num_format( - "#,##0." + "0" * currency_id.decimal_places - ) - self.format_percent_bold_italic = workbook.add_format( - {"bold": True, "italic": True} - ) - self.format_percent_bold_italic.set_num_format("#,##0.00%") + currency_id = self.env["res.company"]._default_currency_id() + report_data["formats"] = { + "format_bold": workbook.add_format({"bold": True}), + "format_right": workbook.add_format({"align": "right"}), + "format_left": workbook.add_format({"align": "left"}), + "format_right_bold_italic": workbook.add_format( + {"align": "right", "bold": True, "italic": True} + ), + "format_header_left": workbook.add_format( + {"bold": True, "border": True, "bg_color": "#FFFFCC"} + ), + "format_header_center": workbook.add_format( + {"bold": True, "align": "center", "border": True, "bg_color": "#FFFFCC"} + ), + "format_header_right": workbook.add_format( + {"bold": True, "align": "right", "border": True, "bg_color": "#FFFFCC"} + ), + "format_header_amount": workbook.add_format( + {"bold": True, "border": True, "bg_color": "#FFFFCC"} + ).set_num_format("#,##0." + "0" * currency_id.decimal_places), + "format_amount": workbook.add_format().set_num_format( + "#,##0." + "0" * currency_id.decimal_places + ), + "format_amount_bold": workbook.add_format({"bold": True}).set_num_format( + "#,##0." + "0" * currency_id.decimal_places + ), + "format_percent_bold_italic": workbook.add_format( + {"bold": True, "italic": True} + ).set_num_format("#,##0.00%"), + } - def _set_column_width(self): + def _set_column_width(self, report_data): """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"]) + for position, column in report_data["columns"].items(): + report_data["sheet"].set_column(position, position, column["width"]) - def _write_report_title(self, title): + def _write_report_title(self, title, report_data): """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, + report_data["sheet"].merge_range( + report_data["row_pos"], 0, - self.row_pos, - len(self.columns) - 1, + report_data["row_pos"], + len(report_data["columns"]) - 1, title, - self.format_bold, + report_data["formats"]["format_bold"], ) - self.row_pos += 3 + report_data["row_pos"] += 3 - def _write_report_footer(self, footer): + def _write_report_footer(self, footer, report_data): """Write report footer . Columns are defined with `_get_report_columns` method. """ if footer: - self.row_pos += 1 - self.sheet.merge_range( - self.row_pos, + report_data["row_pos"] += 1 + report_data["sheet"].merge_range( + report_data["row_pos"], 0, - self.row_pos, - len(self.columns) - 1, + report_data["row_pos"], + len(report_data["columns"]) - 1, footer, - self.format_left, + report_data["formats"]["format_left"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def _write_filters(self, filters): + def _write_filters(self, filters, report_data): """Write one line per filters on starting on current line. Columns number for filter name is defined with `_get_col_count_filter_name` method. @@ -154,91 +134,102 @@ class AbstractReportXslx(models.AbstractModel): col_count_filter_value = self._get_col_count_filter_value() col_value = col_name + col_count_filter_name + 1 for title, value in filters: - self.sheet.merge_range( - self.row_pos, + report_data["sheet"].merge_range( + report_data["row_pos"], col_name, - self.row_pos, + report_data["row_pos"], col_name + col_count_filter_name - 1, title, - self.format_header_left, + report_data["formats"]["format_header_left"], ) - self.sheet.merge_range( - self.row_pos, + report_data["sheet"].merge_range( + report_data["row_pos"], col_value, - self.row_pos, + report_data["row_pos"], col_value + col_count_filter_value - 1, value, ) - self.row_pos += 1 - self.row_pos += 2 + report_data["row_pos"] += 1 + report_data["row_pos"] += 2 - def write_array_title(self, title): + def write_array_title(self, title, report_data): """Write array title on current line using all defined columns width. Columns are defined with `_get_report_columns` method. """ - self.sheet.merge_range( - self.row_pos, + report_data["sheet"].merge_range( + report_data["row_pos"], 0, - self.row_pos, - len(self.columns) - 1, + report_data["row_pos"], + len(report_data["columns"]) - 1, title, - self.format_bold, + report_data["formats"]["format_bold"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def write_array_header(self): + def write_array_header(self, report_data): """Write array header on current line using all defined columns name. 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 + for col_pos, column in report_data["columns"].items(): + report_data["sheet"].write( + report_data["row_pos"], + col_pos, + column["header"], + report_data["formats"]["format_header_center"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def write_line(self, line_object): + def write_line(self, line_object, report_data): """Write a line on current line using all defined columns field name. Columns are defined with `_get_report_columns` method. """ - for col_pos, column in self.columns.items(): + for col_pos, column in report_data["columns"].items(): 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 + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value.name or "", + report_data["formats"]["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 + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value or "", + report_data["formats"]["format_bold"], ) else: - self.sheet.write_string(self.row_pos, col_pos, value or "") + report_data["sheet"].write_string( + report_data["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 + cell_format = report_data["formats"]["format_amount_bold"] else: - cell_format = self.format_amount - self.sheet.write_number( - self.row_pos, col_pos, float(value), cell_format + cell_format = report_data["formats"]["format_amount"] + report_data["sheet"].write_number( + report_data["row_pos"], col_pos, float(value), cell_format ) elif cell_type == "amount_currency": if line_object.currency_id: - format_amt = self._get_currency_amt_format(line_object) - self.sheet.write_number( - self.row_pos, col_pos, float(value), format_amt + format_amt = self._get_currency_amt_format(line_object, report_data) + report_data["sheet"].write_number( + report_data["row_pos"], col_pos, float(value), format_amt ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def write_line_from_dict(self, line_dict): + def write_line_from_dict(self, line_dict, report_data): """Write a line on current line""" - for col_pos, column in self.columns.items(): + for col_pos, column in report_data["columns"].items(): value = line_dict.get(column["field"], False) cell_type = column.get("type", "string") if cell_type == "string": @@ -246,8 +237,11 @@ class AbstractReportXslx(models.AbstractModel): 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 + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value or "", + report_data["formats"]["format_bold"], ) else: if ( @@ -256,223 +250,302 @@ class AbstractReportXslx(models.AbstractModel): and not isinstance(value, int) ): value = value and value.strftime("%d/%m/%Y") - self.sheet.write_string(self.row_pos, col_pos, value or "") + report_data["sheet"].write_string( + report_data["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 + cell_format = report_data["formats"]["format_amount_bold"] else: - cell_format = self.format_amount - self.sheet.write_number( - self.row_pos, col_pos, float(value), cell_format + cell_format = report_data["formats"]["format_amount"] + report_data["sheet"].write_number( + report_data["row_pos"], col_pos, float(value), cell_format ) elif cell_type == "amount_currency": if line_dict.get("currency_name", False): - format_amt = self._get_currency_amt_format_dict(line_dict) - self.sheet.write_number( - self.row_pos, col_pos, float(value), format_amt + format_amt = self._get_currency_amt_format_dict( + line_dict, report_data + ) + report_data["sheet"].write_number( + report_data["row_pos"], col_pos, float(value), format_amt ) elif cell_type == "currency_name": - self.sheet.write_string( - self.row_pos, col_pos, value or "", self.format_right + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value or "", + report_data["formats"]["format_right"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def write_initial_balance(self, my_object, label): + def write_initial_balance(self, my_object, label, report_data): """Write a specific initial balance line on current line using defined columns field_initial_balance name. Columns are defined with `_get_report_columns` method. """ col_pos_label = self._get_col_pos_initial_balance_label() - self.sheet.write(self.row_pos, col_pos_label, label, self.format_right) - for col_pos, column in self.columns.items(): + report_data["sheet"].write( + report_data["row_pos"], + col_pos_label, + label, + report_data["formats"]["format_right"], + ) + for col_pos, column in report_data["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 "") + report_data["sheet"].write_string( + report_data["row_pos"], col_pos, value or "" + ) elif cell_type == "amount": - self.sheet.write_number( - self.row_pos, col_pos, float(value), self.format_amount + report_data["sheet"].write_number( + report_data["row_pos"], + col_pos, + float(value), + report_data["formats"]["format_amount"], ) elif cell_type == "amount_currency": if my_object.currency_id: - format_amt = self._get_currency_amt_format(my_object) - self.sheet.write_number( - self.row_pos, col_pos, float(value), format_amt + format_amt = self._get_currency_amt_format( + my_object, report_data + ) + report_data["sheet"].write_number( + report_data["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": if my_object.currency_id: - self.sheet.write_string( - self.row_pos, col_pos, value.name or "", self.format_right + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value.name or "", + report_data["formats"]["format_right"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def write_initial_balance_from_dict(self, my_object, label): + def write_initial_balance_from_dict(self, my_object, label, report_data): """Write a specific initial balance line on current line using defined columns field_initial_balance name. Columns are defined with `_get_report_columns` method. """ col_pos_label = self._get_col_pos_initial_balance_label() - self.sheet.write(self.row_pos, col_pos_label, label, self.format_right) - for col_pos, column in self.columns.items(): + report_data["sheet"].write( + report_data["row_pos"], + col_pos_label, + label, + report_data["formats"]["format_right"], + ) + for col_pos, column in report_data["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 "") + report_data["sheet"].write_string( + report_data["row_pos"], col_pos, value or "" + ) elif cell_type == "amount": - self.sheet.write_number( - self.row_pos, col_pos, float(value), self.format_amount + report_data["sheet"].write_number( + report_data["row_pos"], + col_pos, + float(value), + report_data["formats"]["format_amount"], ) elif cell_type == "amount_currency": if my_object["currency_id"]: - format_amt = self._get_currency_amt_format(my_object) - self.sheet.write_number( - self.row_pos, col_pos, float(value), format_amt + format_amt = self._get_currency_amt_format( + my_object, report_data + ) + report_data["sheet"].write_number( + report_data["row_pos"], col_pos, float(value), format_amt ) elif column.get("field_currency_balance"): value = my_object.get(column["field_currency_balance"], False) cell_type = column.get("type", "string") if cell_type == "many2one": if my_object["currency_id"]: - self.sheet.write_string( - self.row_pos, col_pos, value.name or "", self.format_right + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value.name or "", + report_data["formats"]["format_right"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def write_ending_balance(self, my_object, name, label): + def write_ending_balance(self, my_object, name, label, report_data): """Write a specific ending balance line on current line using defined columns field_final_balance name. Columns are defined with `_get_report_columns` method. """ - for i in range(0, len(self.columns)): - self.sheet.write(self.row_pos, i, "", self.format_header_right) + for i in range(0, len(report_data["columns"])): + report_data["sheet"].write( + report_data["row_pos"], + i, + "", + report_data["formats"]["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, + report_data["sheet"].merge_range( + report_data["row_pos"], 0, - self.row_pos, + report_data["row_pos"], row_count_name - 1, name, - self.format_header_left, + report_data["formats"]["format_header_left"], + ) + report_data["sheet"].write( + report_data["row_pos"], + col_pos_label, + label, + report_data["formats"]["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(): + for col_pos, column in report_data["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 + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value or "", + report_data["formats"]["format_header_right"], ) elif cell_type == "amount": - self.sheet.write_number( - self.row_pos, col_pos, float(value), self.format_header_amount + report_data["sheet"].write_number( + report_data["row_pos"], + col_pos, + float(value), + report_data["formats"]["format_header_amount"], ) elif cell_type == "amount_currency": if my_object.currency_id: - format_amt = self._get_currency_amt_header_format(my_object) - self.sheet.write_number( - self.row_pos, col_pos, float(value), format_amt + format_amt = self._get_currency_amt_header_format( + my_object, report_data + ) + report_data["sheet"].write_number( + report_data["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": if my_object.currency_id: - self.sheet.write_string( - self.row_pos, + report_data["sheet"].write_string( + report_data["row_pos"], col_pos, value.name or "", - self.format_header_right, + report_data["formats"]["format_header_right"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def write_ending_balance_from_dict(self, my_object, name, label): + def write_ending_balance_from_dict(self, my_object, name, label, report_data): """Write a specific ending balance line on current line using defined columns field_final_balance name. Columns are defined with `_get_report_columns` method. """ - for i in range(0, len(self.columns)): - self.sheet.write(self.row_pos, i, "", self.format_header_right) + for i in range(0, len(report_data["columns"])): + report_data["sheet"].write( + report_data["row_pos"], + i, + "", + report_data["formats"]["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, + report_data["sheet"].merge_range( + report_data["row_pos"], 0, - self.row_pos, + report_data["row_pos"], row_count_name - 1, name, - self.format_header_left, + report_data["formats"]["format_header_left"], + ) + report_data["sheet"].write( + report_data["row_pos"], + col_pos_label, + label, + report_data["formats"]["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(): + for col_pos, column in report_data["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 + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value or "", + report_data["formats"]["format_header_right"], ) elif cell_type == "amount": - self.sheet.write_number( - self.row_pos, col_pos, float(value), self.format_header_amount + report_data["sheet"].write_number( + report_data["row_pos"], + col_pos, + float(value), + report_data["formats"]["format_header_amount"], ) elif cell_type == "amount_currency": if my_object["currency_id"] and value: - format_amt = self._get_currency_amt_format_dict(my_object) - self.sheet.write_number( - self.row_pos, col_pos, float(value), format_amt + format_amt = self._get_currency_amt_format_dict( + my_object, report_data + ) + report_data["sheet"].write_number( + report_data["row_pos"], col_pos, float(value), format_amt ) elif column.get("field_currency_balance"): value = my_object.get(column["field_currency_balance"], False) cell_type = column.get("type", "string") if cell_type == "many2one": if my_object["currency_id"]: - self.sheet.write_string( - self.row_pos, col_pos, value or "", self.format_header_right + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value or "", + report_data["formats"]["format_header_right"], ) elif cell_type == "currency_name": - self.sheet.write_string( - self.row_pos, col_pos, value or "", self.format_header_right + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value or "", + report_data["formats"]["format_header_right"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 - def _get_currency_amt_format(self, line_object): + def _get_currency_amt_format(self, line_object, report_data): """ Return amount format specific for each currency. """ if "account_group_id" in line_object and line_object["account_group_id"]: - format_amt = self.format_amount_bold + format_amt = report_data["formats"]["format_amount_bold"] field_prefix = "format_amount_bold" else: - format_amt = self.format_amount + format_amt = report_data["formats"]["format_amount"] field_prefix = "format_amount" if "currency_id" in line_object and line_object.get("currency_id", False): 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() - self.field_name = format_amt + format_amt = report_data["workbook"].add_format() + report_data["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): + def _get_currency_amt_format_dict(self, line_dict, report_data): """ Return amount format specific for each currency. """ if line_dict.get("account_group_id", False) and line_dict["account_group_id"]: - format_amt = self.format_amount_bold + format_amt = report_data["formats"]["format_amount_bold"] field_prefix = "format_amount_bold" else: - format_amt = self.format_amount + format_amt = report_data["formats"]["format_amount"] field_prefix = "format_amount" if line_dict.get("currency_id", False) and line_dict["currency_id"]: if isinstance(line_dict["currency_id"], int): @@ -483,49 +556,49 @@ class AbstractReportXslx(models.AbstractModel): if hasattr(self, field_name): format_amt = getattr(self, field_name) else: - format_amt = self.workbook.add_format() - self.field_name = format_amt + format_amt = report_data["workbook"].add_format() + report_data["field_name"] = format_amt format_amount = "#,##0." + ("0" * currency.decimal_places) format_amt.set_num_format(format_amount) return format_amt - def _get_currency_amt_header_format(self, line_object): + def _get_currency_amt_header_format(self, line_object, report_data): """ Return amount header format for each currency. """ - format_amt = self.format_header_amount + format_amt = report_data["formats"]["format_header_amount"] if line_object.currency_id: 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( + format_amt = report_data["workbook"].add_format( {"bold": True, "border": True, "bg_color": "#FFFFCC"} ) - self.field_name = format_amt + report_data["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): + def _get_currency_amt_header_format_dict(self, line_object, report_data): """ Return amount header format for each currency. """ - format_amt = self.format_header_amount + format_amt = report_data["formats"]["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( + format_amt = report_data["workbook"].add_format( {"bold": True, "border": True, "bg_color": "#FFFFCC"} ) - self.field_name = format_amt + report_data["field_name"] = format_amt format_amount = "#,##0." + ( "0" * line_object["currency_id"].decimal_places ) format_amt.set_num_format(format_amount) return format_amt - def _generate_report_content(self, workbook, report, data): + def _generate_report_content(self, workbook, report, data, report_data): """ Allow to fetch report content to be displayed. """ diff --git a/account_financial_report/report/aged_partner_balance_xlsx.py b/account_financial_report/report/aged_partner_balance_xlsx.py index fc25b61d..def43e97 100644 --- a/account_financial_report/report/aged_partner_balance_xlsx.py +++ b/account_financial_report/report/aged_partner_balance_xlsx.py @@ -1,5 +1,6 @@ # Author: Julien Coux # Copyright 2016 Camptocamp SA +# Copyright 2021 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, models @@ -177,7 +178,7 @@ class AgedPartnerBalanceXslx(models.AbstractModel): def _get_col_pos_final_balance_label(self): return 5 - def _generate_report_content(self, workbook, report, data): + def _generate_report_content(self, workbook, report, data, report_data): res_data = self.env[ "report.account_financial_report.aged_partner_balance" ]._get_report_values(report, data) @@ -187,14 +188,16 @@ 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"], report_data + ) # Display array header for partners lines - self.write_array_header() + self.write_array_header(report_data) # Display partner lines for partner in account["partners"]: - self.write_line_from_dict(partner) + self.write_line_from_dict(partner, report_data) # Display account lines self.write_account_footer_from_dict( @@ -202,45 +205,49 @@ class AgedPartnerBalanceXslx(models.AbstractModel): account, ("Total"), "field_footer_total", - self.format_header_right, - self.format_header_amount, + report_data["formats"]["format_header_right"], + report_data["formats"]["format_header_amount"], False, + report_data, ) self.write_account_footer_from_dict( report, account, ("Percents"), "field_footer_percent", - self.format_right_bold_italic, - self.format_percent_bold_italic, + report_data["formats"]["format_right_bold_italic"], + report_data["formats"]["format_percent_bold_italic"], True, + report_data, ) # 2 lines break - self.row_pos += 2 + report_data["row_pos"] += 2 else: # 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"], report_data + ) # For each partner for partner in account["partners"]: # Write partner title - self.write_array_title(partner["name"]) + self.write_array_title(partner["name"], report_data) # Display array header for move lines - self.write_array_header() + self.write_array_header(report_data) # Display account move lines for line in partner["move_lines"]: - self.write_line_from_dict(line) + self.write_line_from_dict(line, report_data) # Display ending balance line for partner - self.write_ending_balance_from_dict(partner) + self.write_ending_balance_from_dict(partner, report_data) # Line break - self.row_pos += 1 + report_data["row_pos"] += 1 # Display account lines self.write_account_footer_from_dict( @@ -248,9 +255,10 @@ class AgedPartnerBalanceXslx(models.AbstractModel): account, ("Total"), "field_footer_total", - self.format_header_right, - self.format_header_amount, + report_data["formats"]["format_header_right"], + report_data["formats"]["format_header_amount"], False, + report_data, ) self.write_account_footer_from_dict( @@ -258,24 +266,23 @@ class AgedPartnerBalanceXslx(models.AbstractModel): account, ("Percents"), "field_footer_percent", - self.format_right_bold_italic, - self.format_percent_bold_italic, + report_data["formats"]["format_right_bold_italic"], + report_data["formats"]["format_percent_bold_italic"], True, + report_data, ) # 2 lines break - self.row_pos += 2 + report_data["row_pos"] += 2 - def write_ending_balance_from_dict(self, my_object): + def write_ending_balance_from_dict(self, my_object, report_data): """ Specific function to write ending partner balance for Aged Partner Balance """ name = None label = _("Partner cumul aged balance") - super(AgedPartnerBalanceXslx, self).write_ending_balance_from_dict( - my_object, name, label - ) + super().write_ending_balance_from_dict(my_object, name, label, report_data) def write_account_footer_from_dict( self, @@ -286,12 +293,13 @@ class AgedPartnerBalanceXslx(models.AbstractModel): string_format, amount_format, amount_is_percent, + report_data, ): """ Specific function to write account footer for Aged Partner Balance """ col_pos_footer_label = self._get_col_pos_footer_label(report) - for col_pos, column in self.columns.items(): + for col_pos, column in report_data["columns"].items(): if col_pos == col_pos_footer_label or column.get(field_name): if col_pos == col_pos_footer_label: value = label @@ -299,17 +307,19 @@ class AgedPartnerBalanceXslx(models.AbstractModel): 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 + report_data["sheet"].write_string( + report_data["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 + report_data["sheet"].write_number( + report_data["row_pos"], col_pos, number, amount_format ) else: - self.sheet.write_string(self.row_pos, col_pos, "", string_format) + report_data["sheet"].write_string( + report_data["row_pos"], col_pos, "", string_format + ) - self.row_pos += 1 + report_data["row_pos"] += 1 diff --git a/account_financial_report/report/general_ledger_xlsx.py b/account_financial_report/report/general_ledger_xlsx.py index c57c24d3..7f0583a9 100644 --- a/account_financial_report/report/general_ledger_xlsx.py +++ b/account_financial_report/report/general_ledger_xlsx.py @@ -1,6 +1,7 @@ # Author: Damien Crier # Author: Julien Coux # Copyright 2016 Camptocamp SA +# Copyright 2021 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, models @@ -135,7 +136,7 @@ class GeneralLedgerXslx(models.AbstractModel): return 5 # flake8: noqa: C901 - def _generate_report_content(self, workbook, report, data): + def _generate_report_content(self, workbook, report, data, report_data): res_data = self.env[ "report.account_financial_report.general_ledger" ]._get_report_values(report, data) @@ -151,12 +152,13 @@ class GeneralLedgerXslx(models.AbstractModel): for account in general_ledger: # Write account title self.write_array_title( - account["code"] + " - " + accounts_data[account["id"]]["name"] + account["code"] + " - " + accounts_data[account["id"]]["name"], + report_data, ) if not account["partners"]: # Display array header for move lines - self.write_array_header() + self.write_array_header(report_data) # Display initial balance line for account account.update( @@ -170,7 +172,7 @@ class GeneralLedgerXslx(models.AbstractModel): account.update( {"initial_bal_curr": account["init_bal"]["bal_curr"]} ) - self.write_initial_balance_from_dict(account) + self.write_initial_balance_from_dict(account, report_data) # Display account move lines for line in account["move_lines"]: @@ -200,7 +202,7 @@ class GeneralLedgerXslx(models.AbstractModel): "tags": tags, } ) - self.write_line_from_dict(line) + self.write_line_from_dict(line, report_data) # Display ending balance line for account account.update( { @@ -215,16 +217,18 @@ class GeneralLedgerXslx(models.AbstractModel): "final_bal_curr": account["fin_bal"]["bal_curr"], } ) - self.write_ending_balance_from_dict(account) + self.write_ending_balance_from_dict(account, report_data) else: # For each 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"], report_data + ) # Display array header for move lines - self.write_array_header() + self.write_array_header(report_data) # Display initial balance line for partner partner.update( @@ -243,7 +247,7 @@ class GeneralLedgerXslx(models.AbstractModel): "initial_bal_curr": partner["init_bal"]["bal_curr"], } ) - self.write_initial_balance_from_dict(partner) + self.write_initial_balance_from_dict(partner, report_data) # Display account move lines for line in partner["move_lines"]: @@ -275,7 +279,7 @@ class GeneralLedgerXslx(models.AbstractModel): "tags": tags, } ) - self.write_line_from_dict(line) + self.write_line_from_dict(line, report_data) # Display ending balance line for partner partner.update( @@ -293,10 +297,10 @@ class GeneralLedgerXslx(models.AbstractModel): "currency_id": partner["currency_id"].id, } ) - self.write_ending_balance_from_dict(partner) + self.write_ending_balance_from_dict(partner, report_data) # Line break - self.row_pos += 1 + report_data["row_pos"] += 1 if not filter_partner_ids: account.update( @@ -314,20 +318,22 @@ class GeneralLedgerXslx(models.AbstractModel): "currency_id": account["currency_id"].id, } ) - self.write_ending_balance_from_dict(account) + self.write_ending_balance_from_dict(account, report_data) # 2 lines break - self.row_pos += 2 + report_data["row_pos"] += 2 - def write_initial_balance_from_dict(self, my_object): + def write_initial_balance_from_dict(self, my_object, report_data): """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) + super(GeneralLedgerXslx, self).write_initial_balance_from_dict( + my_object, label, report_data + ) - def write_ending_balance_from_dict(self, my_object): + def write_ending_balance_from_dict(self, my_object, report_data): """Specific function to write ending balance for General Ledger""" if "partner" in my_object["type"]: name = my_object["name"] @@ -336,5 +342,5 @@ class GeneralLedgerXslx(models.AbstractModel): name = my_object["code"] + " - " + my_object["name"] label = _("Ending balance") super(GeneralLedgerXslx, self).write_ending_balance_from_dict( - my_object, name, label + my_object, name, label, report_data ) diff --git a/account_financial_report/report/journal_ledger_xlsx.py b/account_financial_report/report/journal_ledger_xlsx.py index 104c531e..b9143389 100644 --- a/account_financial_report/report/journal_ledger_xlsx.py +++ b/account_financial_report/report/journal_ledger_xlsx.py @@ -1,6 +1,7 @@ # Author: Damien Crier # Author: Julien Coux # Copyright 2016 Camptocamp SA +# Copyright 2021 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, models @@ -149,24 +150,28 @@ class JournalLedgerXslx(models.AbstractModel): ], ] - def _generate_report_content(self, workbook, report, data): + def _generate_report_content(self, workbook, report, data, report_data): res_data = self.env[ "report.account_financial_report.journal_ledger" ]._get_report_values(report, data) group_option = report.group_option if group_option == "journal": for ledger in res_data["Journal_Ledgers"]: - self._generate_journal_content(workbook, report, res_data, ledger) + self._generate_journal_content( + workbook, report, res_data, ledger, report_data + ) elif group_option == "none": - self._generate_no_group_content(workbook, report, res_data) + self._generate_no_group_content(workbook, report, res_data, report_data) - def _generate_no_group_content(self, workbook, report, res_data): + def _generate_no_group_content(self, workbook, report, res_data, report_data): self._generate_moves_content( - workbook, "Report", report, res_data, res_data["Moves"] + workbook, "Report", report, res_data, res_data["Moves"], report_data ) - self._generate_no_group_taxes_summary(workbook, report, res_data) + self._generate_no_group_taxes_summary(workbook, report, res_data, report_data) - def _generate_journal_content(self, workbook, report, res_data, ledger): + def _generate_journal_content( + self, workbook, report, res_data, ledger, report_data + ): journal = self.env["account.journal"].browse(ledger["id"]) currency_name = ( journal.currency_id @@ -175,14 +180,16 @@ class JournalLedgerXslx(models.AbstractModel): ) 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"], report_data ) - self._generate_journal_taxes_summary(workbook, ledger) + self._generate_journal_taxes_summary(workbook, ledger, report_data) - def _generate_no_group_taxes_summary(self, workbook, report, res_data): - self._generate_taxes_summary(workbook, "Tax Report", res_data["tax_line_data"]) + def _generate_no_group_taxes_summary(self, workbook, report, res_data, report_data): + self._generate_taxes_summary( + workbook, "Tax Report", res_data["tax_line_data"], report_data + ) - def _generate_journal_taxes_summary(self, workbook, ledger): + def _generate_journal_taxes_summary(self, workbook, ledger, report_data): journal = self.env["account.journal"].browse(ledger["id"]) currency_name = ( journal.currency_id @@ -192,19 +199,23 @@ class JournalLedgerXslx(models.AbstractModel): sheet_name = "Tax - {} ({}) - {}".format( journal.code, currency_name, journal.name ) - self._generate_taxes_summary(workbook, sheet_name, ledger["tax_lines"]) + self._generate_taxes_summary( + workbook, sheet_name, ledger["tax_lines"], report_data + ) - 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() + def _generate_moves_content( + self, workbook, sheet_name, report, res_data, moves, report_data + ): + report_data["workbook"] = workbook + report_data["sheet"] = workbook.add_worksheet(sheet_name) + self._set_column_width(report_data) - self.row_pos = 1 + report_data["row_pos"] = 1 - self.write_array_title(sheet_name) - self.row_pos += 2 + self.write_array_title(sheet_name, report_data) + report_data["row_pos"] += 2 - self.write_array_header() + self.write_array_header(report_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"] @@ -232,16 +243,18 @@ class JournalLedgerXslx(models.AbstractModel): line["move_line_id"], False ), ) - self.write_line_from_dict(line) - self.row_pos += 1 + self.write_line_from_dict(line, report_data) + report_data["row_pos"] += 1 - def _generate_taxes_summary(self, workbook, sheet_name, tax_lines_dict): - self.workbook = workbook - self.sheet = workbook.add_worksheet(sheet_name) + def _generate_taxes_summary( + self, workbook, sheet_name, tax_lines_dict, report_data + ): + report_data["workbook"] = workbook + report_data["sheet"] = workbook.add_worksheet(sheet_name) - self.row_pos = 1 - self.write_array_title(sheet_name) - self.row_pos += 2 + report_data["row_pos"] = 1 + self.write_array_title(sheet_name, report_data) + report_data["row_pos"] += 2 def _get_partner_name(self, partner_id, partner_data): if partner_id in partner_data.keys(): diff --git a/account_financial_report/report/open_items_xlsx.py b/account_financial_report/report/open_items_xlsx.py index 65345775..ce266080 100644 --- a/account_financial_report/report/open_items_xlsx.py +++ b/account_financial_report/report/open_items_xlsx.py @@ -1,5 +1,6 @@ # Author: Julien Coux # Copyright 2016 Camptocamp SA +# Copyright 2021 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, models @@ -100,7 +101,7 @@ class OpenItemsXslx(models.AbstractModel): def _get_col_pos_final_balance_label(self): return 5 - def _generate_report_content(self, workbook, report, data): + def _generate_report_content(self, workbook, report, data, report_data): res_data = self.env[ "report.account_financial_report.open_items" ]._get_report_values(report, data) @@ -116,7 +117,8 @@ class OpenItemsXslx(models.AbstractModel): self.write_array_title( accounts_data[account_id]["code"] + " - " - + accounts_data[account_id]["name"] + + accounts_data[account_id]["name"], + report_data, ) # For each partner @@ -125,10 +127,12 @@ class OpenItemsXslx(models.AbstractModel): for partner_id in Open_items[account_id]: type_object = "partner" # Write partner title - self.write_array_title(partners_data[partner_id]["name"]) + self.write_array_title( + partners_data[partner_id]["name"], report_data + ) # Display array header for move lines - self.write_array_header() + self.write_array_header(report_data) # Display account move lines for line in Open_items[account_id][partner_id]: @@ -140,7 +144,7 @@ class OpenItemsXslx(models.AbstractModel): ], } ) - self.write_line_from_dict(line) + self.write_line_from_dict(line, report_data) # Display ending balance line for partner partners_data[partner_id].update( @@ -155,15 +159,16 @@ class OpenItemsXslx(models.AbstractModel): partners_data[partner_id], type_object, total_amount, + report_data, account_id, partner_id, ) # Line break - self.row_pos += 1 + report_data["row_pos"] += 1 else: # Display array header for move lines - self.write_array_header() + self.write_array_header(report_data) # Display account move lines for line in Open_items[account_id]: @@ -173,19 +178,29 @@ class OpenItemsXslx(models.AbstractModel): "journal": journals_data[line["journal_id"]]["code"], } ) - self.write_line_from_dict(line) + self.write_line_from_dict(line, report_data) # 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 + accounts_data[account_id], + type_object, + report_data, + total_amount, + account_id, ) # 2 lines break - self.row_pos += 2 + report_data["row_pos"] += 2 def write_ending_balance_from_dict( - self, my_object, type_object, total_amount, account_id=False, partner_id=False + self, + my_object, + type_object, + total_amount, + report_data, + account_id=False, + partner_id=False, ): """Specific function to write ending balance for Open Items""" if type_object == "partner": @@ -197,5 +212,5 @@ class OpenItemsXslx(models.AbstractModel): 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, report_data ) diff --git a/account_financial_report/report/trial_balance.py b/account_financial_report/report/trial_balance.py index 147978e0..f37e5663 100644 --- a/account_financial_report/report/trial_balance.py +++ b/account_financial_report/report/trial_balance.py @@ -539,7 +539,7 @@ class TrialBalanceReport(models.AbstractModel): groups_data[group.id].update( { "id": group.id, - "code": group.code_prefix, + "code": group.code_prefix_start, "name": group.name, "parent_id": group.parent_id.id, "parent_path": group.parent_path, @@ -573,7 +573,7 @@ class TrialBalanceReport(models.AbstractModel): { group.id: { "id": group.id, - "code": group.code_prefix, + "code": group.code_prefix_start, "name": group.name, "parent_id": group.parent_id.id, "parent_path": group.parent_path, @@ -620,12 +620,12 @@ class TrialBalanceReport(models.AbstractModel): groups = self.env["account.group"].search([("id", "!=", False)]) groups_data = {} for group in groups: - len_group_code = len(group.code_prefix) + len_group_code = len(group.code_prefix_start) groups_data.update( { group.id: { "id": group.id, - "code": group.code_prefix, + "code": group.code_prefix_start, "name": group.name, "parent_id": group.parent_id.id, "parent_path": group.parent_path, @@ -644,7 +644,7 @@ class TrialBalanceReport(models.AbstractModel): groups_data[group.id]["initial_currency_balance"] = 0.0 groups_data[group.id]["ending_currency_balance"] = 0.0 for account in accounts_data.values(): - if group.code_prefix == account["code"][:len_group_code]: + if group.code_prefix_start == account["code"][:len_group_code]: acc_id = account["id"] group_id = group.id groups_data[group_id]["initial_balance"] += total_amount[acc_id][ diff --git a/account_financial_report/report/trial_balance_xlsx.py b/account_financial_report/report/trial_balance_xlsx.py index f1759ad8..c61424d4 100644 --- a/account_financial_report/report/trial_balance_xlsx.py +++ b/account_financial_report/report/trial_balance_xlsx.py @@ -1,5 +1,6 @@ # Author: Julien Coux # Copyright 2016 Camptocamp SA +# Copyright 2021 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). @@ -173,7 +174,7 @@ class TrialBalanceXslx(models.AbstractModel): def _get_col_count_filter_value(self): return 3 - def _generate_report_content(self, workbook, report, data): + def _generate_report_content(self, workbook, report, data, report_data): res_data = self.env[ "report.account_financial_report.trial_balance" ]._get_report_values(report, data) @@ -188,7 +189,7 @@ class TrialBalanceXslx(models.AbstractModel): limit_hierarchy_level = res_data["limit_hierarchy_level"] if not show_partner_details: # Display array header for account lines - self.write_array_header() + self.write_array_header(report_data) # For each account if not show_partner_details: @@ -197,29 +198,30 @@ class TrialBalanceXslx(models.AbstractModel): if limit_hierarchy_level: if show_hierarchy_level > balance["level"]: # Display account lines - self.write_line_from_dict(balance) + self.write_line_from_dict(balance, report_data) else: - self.write_line_from_dict(balance) + self.write_line_from_dict(balance, report_data) elif hierarchy_on == "computed": if balance["type"] == "account_type": if limit_hierarchy_level: if show_hierarchy_level > balance["level"]: # Display account lines - self.write_line_from_dict(balance) + self.write_line_from_dict(balance, report_data) else: - self.write_line_from_dict(balance) + self.write_line_from_dict(balance, report_data) else: - self.write_line_from_dict(balance) + self.write_line_from_dict(balance, report_data) else: for account_id in total_amount: # Write account title self.write_array_title( accounts_data[account_id]["code"] + "- " - + accounts_data[account_id]["name"] + + accounts_data[account_id]["name"], + report_data, ) # Display array header for partner lines - self.write_array_header() + self.write_array_header(report_data) # For each partner for partner_id in total_amount[account_id]: @@ -228,6 +230,7 @@ class TrialBalanceXslx(models.AbstractModel): self.write_line_from_dict_order( total_amount[account_id][partner_id], partners_data[partner_id], + report_data, ) # Display account footer line @@ -256,16 +259,17 @@ class TrialBalanceXslx(models.AbstractModel): accounts_data[account_id]["code"] + "- " + accounts_data[account_id]["name"], + report_data, ) # Line break - self.row_pos += 2 + report_data["row_pos"] += 2 - def write_line_from_dict_order(self, total_amount, partner_data): + def write_line_from_dict_order(self, total_amount, partner_data, report_data): total_amount.update({"name": str(partner_data["name"])}) - self.write_line_from_dict(total_amount) + self.write_line_from_dict(total_amount, report_data) - def write_line(self, line_object, type_object): + def write_line(self, line_object, type_object, report_data): """Write a line on current line using all defined columns field name. Columns are defined with `_get_report_columns` method. """ @@ -273,33 +277,47 @@ class TrialBalanceXslx(models.AbstractModel): line_object.currency_id = line_object.report_account_id.currency_id elif type_object == "account": line_object.currency_id = line_object.currency_id - super(TrialBalanceXslx, self).write_line(line_object) + super(TrialBalanceXslx, self).write_line(line_object, report_data) - def write_account_footer(self, account, name_value): + def write_account_footer(self, account, name_value, report_data): """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(): + format_amt = self._get_currency_amt_header_format_dict(account, report_data) + for col_pos, column in report_data["columns"].items(): 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 + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value or "", + report_data["formats"]["format_header_left"], ) elif cell_type == "amount": - self.sheet.write_number( - self.row_pos, col_pos, float(value), self.format_header_amount + report_data["sheet"].write_number( + report_data["row_pos"], + col_pos, + float(value), + report_data["formats"]["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 + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + value.name or "", + report_data["formats"]["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) + report_data["sheet"].write_number( + report_data["row_pos"], col_pos, float(value), format_amt + ) else: - self.sheet.write_string( - self.row_pos, col_pos, "", self.format_header_right + report_data["sheet"].write_string( + report_data["row_pos"], + col_pos, + "", + report_data["formats"]["format_header_right"], ) - self.row_pos += 1 + report_data["row_pos"] += 1 diff --git a/account_financial_report/report/vat_report.py b/account_financial_report/report/vat_report.py index 0b61bbb4..c529da7c 100644 --- a/account_financial_report/report/vat_report.py +++ b/account_financial_report/report/vat_report.py @@ -65,7 +65,6 @@ class VATReport(models.AbstractModel): "tax_line_id", "tax_ids", "analytic_tag_ids", - "tag_ids", ] tax_move_lines = self.env["account.move.line"].search_read( domain=tax_domain, diff --git a/account_financial_report/report/vat_report_xlsx.py b/account_financial_report/report/vat_report_xlsx.py index 75f2f30c..9984d02c 100644 --- a/account_financial_report/report/vat_report_xlsx.py +++ b/account_financial_report/report/vat_report_xlsx.py @@ -1,4 +1,5 @@ # Copyright 2018 Forest and Biomass Romania +# Copyright 2021 Tecnativa - João Marques # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). from odoo import _, models @@ -42,19 +43,19 @@ class VATReportXslx(models.AbstractModel): def _get_col_count_filter_value(self): return 2 - def _generate_report_content(self, workbook, report, data): + def _generate_report_content(self, workbook, report, data, report_data): res_data = self.env[ "report.account_financial_report.vat_report" ]._get_report_values(report, data) vat_report = res_data["vat_report"] tax_detail = res_data["tax_detail"] # For each tax_tag tax_group - self.write_array_header() + self.write_array_header(report_data) for tag_or_group in vat_report: # Write taxtag line - self.write_line_from_dict(tag_or_group) + self.write_line_from_dict(tag_or_group, report_data) # For each tax if detail taxes if tax_detail: for tax in tag_or_group["taxes"]: - self.write_line_from_dict(tax) + self.write_line_from_dict(tax, report_data) diff --git a/account_financial_report/reports.xml b/account_financial_report/reports.xml index f6d13a23..4f9650d2 100644 --- a/account_financial_report/reports.xml +++ b/account_financial_report/reports.xml @@ -1,120 +1,5 @@ - - - - - - - - - - - - - - - - - - - Account financial report qweb paperformat @@ -131,27 +16,111 @@ 10 110 + + + + General Ledger + general.ledger.report.wizard + qweb-pdf + account_financial_report.general_ledger + account_financial_report.general_ledger + + General Ledger + general.ledger.report.wizard + qweb-html + account_financial_report.general_ledger + account_financial_report.general_ledger + + + ournal Ledger + journal.ledger.report.wizard + qweb-pdf + account_financial_report.journal_ledger + account_financial_report.journal_ledger + + Journal Ledger + journal.ledger.report.wizard + qweb-html + account_financial_report.journal_ledger + account_financial_report.journal_ledger + + + Trial Balance + trial.balance.report.wizard + qweb-pdf + account_financial_report.trial_balance + account_financial_report.trial_balance + + Trial Balance + trial.balance.report.wizard + qweb-html + account_financial_report.trial_balance + account_financial_report.trial_balance + + + Open Items + open.items.report.wizard + qweb-pdf + account_financial_report.open_items + account_financial_report.open_items + + Open Items + open.items.report.wizard + qweb-html + account_financial_report.open_items + account_financial_report.open_items + + + Aged Partner Balance + aged.partner.balance.report.wizard + qweb-pdf + account_financial_report.aged_partner_balance + account_financial_report.aged_partner_balance + + Aged Partner Balance + aged.partner.balance.report.wizard + qweb-html + account_financial_report.aged_partner_balance + account_financial_report.aged_partner_balance + + + VAT Report + vat.report.wizard + qweb-pdf + account_financial_report.vat_report + account_financial_report.vat_report + + VAT Report + vat.report.wizard + qweb-html + account_financial_report.vat_report + account_financial_report.vat_report + + General Ledger XLSX diff --git a/account_financial_report/security/ir.model.access.csv b/account_financial_report/security/ir.model.access.csv new file mode 100644 index 00000000..9416c699 --- /dev/null +++ b/account_financial_report/security/ir.model.access.csv @@ -0,0 +1,7 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_aged_partner_balance_report_wizard,access_aged_partner_balance_report_wizard,model_aged_partner_balance_report_wizard,base.group_user,1,1,1,1 +access_general_ledger_report_wizard,access_general_ledger_report_wizard,model_general_ledger_report_wizard,base.group_user,1,1,1,1 +access_journal_ledger_report_wizard,access_journal_ledger_report_wizard,model_journal_ledger_report_wizard,base.group_user,1,1,1,1 +access_open_items_report_wizard,access_open_items_report_wizard,model_open_items_report_wizard,base.group_user,1,1,1,1 +access_trial_balance_report_wizard,access_trial_balance_report_wizard,model_trial_balance_report_wizard,base.group_user,1,1,1,1 +access_vat_report_wizard,access_vat_report_wizard,model_vat_report_wizard,base.group_user,1,1,1,1 diff --git a/account_financial_report/static/description/index.html b/account_financial_report/static/description/index.html index 40a656f0..d7900a6c 100644 --- a/account_financial_report/static/description/index.html +++ b/account_financial_report/static/description/index.html @@ -3,7 +3,7 @@ - + Account Financial Reports