diff --git a/oca_dependencies.txt b/oca_dependencies.txt new file mode 100644 index 0000000..6da85e0 --- /dev/null +++ b/oca_dependencies.txt @@ -0,0 +1 @@ +reporting-engine diff --git a/privacy_partner_report/README.rst b/privacy_partner_report/README.rst new file mode 100644 index 0000000..b549c5e --- /dev/null +++ b/privacy_partner_report/README.rst @@ -0,0 +1,93 @@ +====================== +Privacy Partner Report +====================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fdata--protection-lightgray.png?logo=github + :target: https://github.com/OCA/data-protection/tree/12.0/privacy_partner_report + :alt: OCA/data-protection +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/data-protection-12-0/data-protection-12-0-privacy_partner_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/263/12.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module helps a company to identify all the transactions that a specific +partner is involved in, with the possibility to export the associated data. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +To use this module, you need to: + +#. Go to menu of ``Privacy > Reports > Partner Report``. +#. Select a partner, and then wait some seconds until a list of models appear. +#. Click on ``Export XLSX``. + +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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Eficent + +Contributors +~~~~~~~~~~~~ + +* Miquel Raïch +* Katja Matthes +* TechUltra Solutions Pvt. Ltd. + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +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. + +.. |maintainer-mreficent| image:: https://github.com/mreficent.png?size=40px + :target: https://github.com/mreficent + :alt: mreficent + +Current `maintainer `__: + +|maintainer-mreficent| + +This module is part of the `OCA/data-protection `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/privacy_partner_report/__init__.py b/privacy_partner_report/__init__.py new file mode 100644 index 0000000..c4e388b --- /dev/null +++ b/privacy_partner_report/__init__.py @@ -0,0 +1,2 @@ +from . import report +from . import wizard diff --git a/privacy_partner_report/__manifest__.py b/privacy_partner_report/__manifest__.py new file mode 100644 index 0000000..a3d98fe --- /dev/null +++ b/privacy_partner_report/__manifest__.py @@ -0,0 +1,19 @@ +# Copyright 2018 Eficent Business and IT Consulting Services S.L. +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html +{ + "name": "Privacy Partner Report", + "version": "13.0.1.0.0", + "category": "GDPR", + "summary": "Show the transactions that a specific partner is involved in.", + "author": "Eficent, " "Odoo Community Association (OCA)", + "website": "https://github.com/OCA/data-protection/", + "license": "AGPL-3", + "depends": ["privacy", "report_xlsx"], + "data": [ + "wizard/privacy_report_partner_wizard.xml", + "views/privacy_report.xml", + "views/privacy_menu_view.xml", + ], + "installable": True, + "maintainers": ["mreficent"], +} diff --git a/privacy_partner_report/i18n/it.po b/privacy_partner_report/i18n/it.po new file mode 100644 index 0000000..487201c --- /dev/null +++ b/privacy_partner_report/i18n/it.po @@ -0,0 +1,174 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * privacy_partner_report +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"PO-Revision-Date: 2019-06-07 15:38+0000\n" +"Last-Translator: Sergio Zanchetta \n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 3.6.1\n" + +#. module: privacy_partner_report +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Select a company
" +msgstr "Selezionare un'azienda
" + +#. module: privacy_partner_report +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Select a partner
" +msgstr "Selezionare un partner
" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__company_id +msgid "Company" +msgstr "Azienda" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__create_uid +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__create_uid +msgid "Created by" +msgstr "Creato da" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__create_date +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__create_date +msgid "Created on" +msgstr "Creato il" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__name +msgid "Database Table" +msgstr "Tabella database" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__display_name +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__display_name +#: model:ir.model.fields,field_description:privacy_partner_report.field_report_privacy_partner_report_report_partner_xlsx__display_name +msgid "Display Name" +msgstr "Nome visualizzato" + +#. module: privacy_partner_report +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Export XLSX" +msgstr "Esporta XLSX" + +#. module: privacy_partner_report +#: code:addons/privacy_partner_report/wizard/privacy_report_partner.py:121 +#, python-format +msgid "Form content is missing, this report cannot be printed." +msgstr "Modulo senza contenuto, impossibile stampare il resoconto." + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__id +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__id +#: model:ir.model.fields,field_description:privacy_partner_report.field_report_privacy_partner_report_report_partner_xlsx__id +msgid "ID" +msgstr "ID" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data____last_update +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report____last_update +#: model:ir.model.fields,field_description:privacy_partner_report.field_report_privacy_partner_report_report_partner_xlsx____last_update +msgid "Last Modified on" +msgstr "Ultima modifica il" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__write_uid +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__write_uid +msgid "Last Updated by" +msgstr "Ultimo aggiornamento di" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__write_date +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__write_date +msgid "Last Updated on" +msgstr "Ultimo aggiornamento il" + +#. module: privacy_partner_report +#: model:ir.model.fields,help:privacy_partner_report.field_privacy_partner_data__res_ids +msgid "List of Related Document IDs" +msgstr "Elenco ID dei documenti collegati" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__model_id +msgid "Models" +msgstr "Modelli" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__table_ids +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Models with related partner data" +msgstr "Modelli con dati dei partner collegati" + +#. module: privacy_partner_report +#: code:addons/privacy_partner_report/wizard/privacy_report_partner.py:66 +#, python-format +msgid "No data for this partner." +msgstr "Nessun dato per questo partner." + +#. module: privacy_partner_report +#: code:addons/privacy_partner_report/wizard/privacy_report_partner.py:125 +#, python-format +msgid "No provided partner." +msgstr "Nessun partner assegnato." + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__count_rows +msgid "Number of lines" +msgstr "Numero di righe" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__partner_id +msgid "Partner" +msgstr "Partner" + +#. module: privacy_partner_report +#: code:addons/privacy_partner_report/report/privacy_partner_xlsx.py:31 +#, python-format +msgid "Partner Data" +msgstr "Dati partner" + +#. module: privacy_partner_report +#: model:ir.actions.act_window,name:privacy_partner_report.action_privacy_partner_menu +#: model:ir.ui.menu,name:privacy_partner_report.menu_privacy_report_privacy_report +msgid "Partner Report" +msgstr "Resoconto partner" + +#. module: privacy_partner_report +#: model:ir.actions.report,name:privacy_partner_report.report_partner_xlsx +#: model:ir.model,name:privacy_partner_report.model_privacy_partner_data +msgid "Privacy Partner Data" +msgstr "Dati privacy del partner" + +#. module: privacy_partner_report +#: model:ir.model,name:privacy_partner_report.model_privacy_partner_report +msgid "Privacy Partner Report" +msgstr "Resoconto privacy del partner" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__res_ids +msgid "Related Document IDs" +msgstr "ID documenti collegati" + +#. module: privacy_partner_report +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Report Options" +msgstr "Opzioni resoconto" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__field_type +msgid "Type" +msgstr "Tipo" + +#. module: privacy_partner_report +#: model:ir.model,name:privacy_partner_report.model_report_privacy_partner_report_report_partner_xlsx +msgid "report.privacy_partner_report.report_partner_xlsx" +msgstr "report.privacy_partner_report.report_partner_xlsx" diff --git a/privacy_partner_report/i18n/privacy_partner_report.pot b/privacy_partner_report/i18n/privacy_partner_report.pot new file mode 100644 index 0000000..5db9cca --- /dev/null +++ b/privacy_partner_report/i18n/privacy_partner_report.pot @@ -0,0 +1,172 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * privacy_partner_report +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 12.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: <>\n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: privacy_partner_report +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Select a company
" +msgstr "" + +#. module: privacy_partner_report +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Select a partner
" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__company_id +msgid "Company" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__create_uid +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__create_uid +msgid "Created by" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__create_date +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__create_date +msgid "Created on" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__name +msgid "Database Table" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__display_name +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__display_name +#: model:ir.model.fields,field_description:privacy_partner_report.field_report_privacy_partner_report_report_partner_xlsx__display_name +msgid "Display Name" +msgstr "" + +#. module: privacy_partner_report +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Export XLSX" +msgstr "" + +#. module: privacy_partner_report +#: code:addons/privacy_partner_report/wizard/privacy_report_partner.py:121 +#, python-format +msgid "Form content is missing, this report cannot be printed." +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__id +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__id +#: model:ir.model.fields,field_description:privacy_partner_report.field_report_privacy_partner_report_report_partner_xlsx__id +msgid "ID" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data____last_update +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report____last_update +#: model:ir.model.fields,field_description:privacy_partner_report.field_report_privacy_partner_report_report_partner_xlsx____last_update +msgid "Last Modified on" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__write_uid +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__write_date +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__write_date +msgid "Last Updated on" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,help:privacy_partner_report.field_privacy_partner_data__res_ids +msgid "List of Related Document IDs" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__model_id +msgid "Models" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__table_ids +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Models with related partner data" +msgstr "" + +#. module: privacy_partner_report +#: code:addons/privacy_partner_report/wizard/privacy_report_partner.py:66 +#, python-format +msgid "No data for this partner." +msgstr "" + +#. module: privacy_partner_report +#: code:addons/privacy_partner_report/wizard/privacy_report_partner.py:125 +#, python-format +msgid "No provided partner." +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__count_rows +msgid "Number of lines" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_report__partner_id +msgid "Partner" +msgstr "" + +#. module: privacy_partner_report +#: code:addons/privacy_partner_report/report/privacy_partner_xlsx.py:31 +#, python-format +msgid "Partner Data" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.actions.act_window,name:privacy_partner_report.action_privacy_partner_menu +#: model:ir.ui.menu,name:privacy_partner_report.menu_privacy_report_privacy_report +msgid "Partner Report" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.actions.report,name:privacy_partner_report.report_partner_xlsx +#: model:ir.model,name:privacy_partner_report.model_privacy_partner_data +msgid "Privacy Partner Data" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model,name:privacy_partner_report.model_privacy_partner_report +msgid "Privacy Partner Report" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__res_ids +msgid "Related Document IDs" +msgstr "" + +#. module: privacy_partner_report +#: model_terms:ir.ui.view,arch_db:privacy_partner_report.privacy_partner_report_wizard +msgid "Report Options" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model.fields,field_description:privacy_partner_report.field_privacy_partner_data__field_type +msgid "Type" +msgstr "" + +#. module: privacy_partner_report +#: model:ir.model,name:privacy_partner_report.model_report_privacy_partner_report_report_partner_xlsx +msgid "report.privacy_partner_report.report_partner_xlsx" +msgstr "" + diff --git a/privacy_partner_report/readme/CONTRIBUTORS.rst b/privacy_partner_report/readme/CONTRIBUTORS.rst new file mode 100644 index 0000000..a7c1465 --- /dev/null +++ b/privacy_partner_report/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* Miquel Raïch +* Katja Matthes +* TechUltra Solutions Pvt. Ltd. diff --git a/privacy_partner_report/readme/DESCRIPTION.rst b/privacy_partner_report/readme/DESCRIPTION.rst new file mode 100644 index 0000000..1f0334f --- /dev/null +++ b/privacy_partner_report/readme/DESCRIPTION.rst @@ -0,0 +1,2 @@ +This module helps a company to identify all the transactions that a specific +partner is involved in, with the possibility to export the associated data. diff --git a/privacy_partner_report/readme/USAGE.rst b/privacy_partner_report/readme/USAGE.rst new file mode 100644 index 0000000..5b27d0e --- /dev/null +++ b/privacy_partner_report/readme/USAGE.rst @@ -0,0 +1,5 @@ +To use this module, you need to: + +#. Go to menu of ``Privacy > Reports > Partner Report``. +#. Select a partner, and then wait some seconds until a list of models appear. +#. Click on ``Export XLSX``. diff --git a/privacy_partner_report/report/__init__.py b/privacy_partner_report/report/__init__.py new file mode 100644 index 0000000..c7f3d0d --- /dev/null +++ b/privacy_partner_report/report/__init__.py @@ -0,0 +1 @@ +from . import privacy_partner_xlsx diff --git a/privacy_partner_report/report/privacy_partner_xlsx.py b/privacy_partner_report/report/privacy_partner_xlsx.py new file mode 100644 index 0000000..f7e788d --- /dev/null +++ b/privacy_partner_report/report/privacy_partner_xlsx.py @@ -0,0 +1,83 @@ +# Copyright 2018 Eficent Business and IT Consulting Services S.L. +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html + +import logging + +from odoo import models +from odoo.tools.translate import _ + +_logger = logging.getLogger(__name__) + + +class ReportPartnerXlsx(models.AbstractModel): + _name = "report.privacy_partner_report.report_partner_xlsx" + _inherit = "report.report_xlsx.abstract" + + def _search_longest_row(self, tables): + res = 0 + for table in tables: + for model in tables[table]: + if len(tables[table][model]) > 0: + if len(tables[table][model][0]) > res: + res = len(tables[table][model][0]) + return res + + def generate_xlsx_report(self, workbook, data, objects): + for o in objects: + report_data = o.compute_data_for_report(data) + partner = report_data["form"].get("partner_id", False) + partner = self.env["res.partner"].sudo().browse(partner[0]) + workbook.set_properties( + {"comments": "Created with Python and XlsxWriter from Odoo"} + ) + sheet = workbook.add_worksheet(_("Partner Data")) + sheet.set_landscape() + sheet.fit_to_pages(1, 0) + sheet.set_zoom(75) + sheet.set_column(0, self._search_longest_row(report_data["tables"]), 25) + title_style = workbook.add_format( + {"bold": True, "bg_color": "#FFFFCC", "border": 2} + ) + sheet.set_row(0, None, None, {"collapsed": 1}) + sheet.write_row(1, 0, ["Partner: " + partner.display_name], title_style) + i = 3 + first_row = i + 2 + for table in sorted(report_data["tables"].keys()): + for model in sorted(report_data["tables"][table].keys()): + rows = len(report_data["tables"][table][model]) + if rows: + style = workbook.add_format() + style.set_bold(True) + style.set_border(2) + sheet.write_row(i, 0, [model], style) + i += 1 + j = 0 + for column in report_data["tables"][table][model][0]: + style = workbook.add_format() + style.set_bold(True) + if j == 0: + style.set_left(1) + if j == len(report_data["tables"][table][model][0]) - 1: + style.set_right(1) + style.set_top(1) + style.set_bottom(1) + sheet.write_row(i, j, [column], style) + j += 1 + for row in report_data["tables"][table][model]: + i += 1 + j = 0 + for column in row: + style = workbook.add_format() + if j == 0: + style.set_left(1) + if j == len(row) - 1: + style.set_right(1) + if i == rows + first_row - 1: + style.set_bottom(1) + if row[column]: + sheet.write_row(i, j, [row[column]], style) + else: + sheet.write_row(i, j, [""], style) + j += 1 + i += 2 + first_row = i + 2 diff --git a/privacy_partner_report/static/description/icon.png b/privacy_partner_report/static/description/icon.png new file mode 100644 index 0000000..f36112b Binary files /dev/null and b/privacy_partner_report/static/description/icon.png differ diff --git a/privacy_partner_report/static/description/index.html b/privacy_partner_report/static/description/index.html new file mode 100644 index 0000000..9c9feb3 --- /dev/null +++ b/privacy_partner_report/static/description/index.html @@ -0,0 +1,434 @@ + + + + + + +Privacy Partner Report + + + +
+

Privacy Partner Report

+ + +

Beta License: AGPL-3 OCA/data-protection Translate me on Weblate Try me on Runbot

+

This module helps a company to identify all the transactions that a specific +partner is involved in, with the possibility to export the associated data.

+

Table of contents

+ +
+

Usage

+

To use this module, you need to:

+
    +
  1. Go to menu of Privacy > Reports > Partner Report.
  2. +
  3. Select a partner, and then wait some seconds until a list of models appear.
  4. +
  5. Click on Export XLSX.
  6. +
+
+
+

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.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Eficent
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+Odoo Community Association +

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.

+

Current maintainer:

+

mreficent

+

This module is part of the OCA/data-protection project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/privacy_partner_report/views/privacy_menu_view.xml b/privacy_partner_report/views/privacy_menu_view.xml new file mode 100644 index 0000000..780adf8 --- /dev/null +++ b/privacy_partner_report/views/privacy_menu_view.xml @@ -0,0 +1,12 @@ + + + + diff --git a/privacy_partner_report/views/privacy_report.xml b/privacy_partner_report/views/privacy_report.xml new file mode 100644 index 0000000..01bc590 --- /dev/null +++ b/privacy_partner_report/views/privacy_report.xml @@ -0,0 +1,11 @@ + + + diff --git a/privacy_partner_report/wizard/__init__.py b/privacy_partner_report/wizard/__init__.py new file mode 100644 index 0000000..f9e260f --- /dev/null +++ b/privacy_partner_report/wizard/__init__.py @@ -0,0 +1 @@ +from . import privacy_report_partner diff --git a/privacy_partner_report/wizard/privacy_report_partner.py b/privacy_partner_report/wizard/privacy_report_partner.py new file mode 100644 index 0000000..534c092 --- /dev/null +++ b/privacy_partner_report/wizard/privacy_report_partner.py @@ -0,0 +1,258 @@ +# Copyright 2018 Eficent Business and IT Consulting Services S.L. +# License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html +import ast + +from odoo import _, api, fields, models +from odoo.exceptions import UserError + + +class PrivacyPartnerReport(models.TransientModel): + _name = "privacy.partner.report" + _description = "Privacy Partner Report" + + company_id = fields.Many2one( + comodel_name="res.company", + string="Company", + required=True, + default=lambda self: self.env.user.company_id, + ) + partner_id = fields.Many2one( + comodel_name="res.partner", string="Partner", required=True, + ) + table_ids = fields.Many2many( + comodel_name="privacy.partner.data", string="Models with related partner data", + ) + + @api.onchange("partner_id") + def _onchange_partner_id(self): + if self.partner_id: + data = self._get_tables_from_partner(self.partner_id) + names = self._get_table_names(data) + tables = self.env["privacy.partner.data"] + for name in sorted(names): + vals = self._get_default_table( + name=name, data=[t for t in data if t[0] == name and not t[5]], + ) + if vals: + tables |= self.env["privacy.partner.data"].create(vals) + self.table_ids = tables + else: + self.table_ids = self.env["privacy.partner.data"] + return { + "domain": {"table_ids": [("id", "in", self.table_ids.ids)]}, + } + + @api.onchange("company_id") + def _onchange_company_id(self): + if not self.company_id: + self.company_id = self.env.user.company_id + return { + "domain": { + "partner_id": [("company_id", "in", [self.company_id.id, False])], + }, + } + + def button_export_xlsx(self): + self.ensure_one() + if not self.table_ids: + raise UserError(_("No data for this partner.")) + return self.check_report(xlsx_report=True) + + def _build_contexts(self, data): + result = {} + result["partner_id"] = data["form"]["partner_id"][0] or False + result["company_id"] = data["form"]["company_id"][0] or False + result["table_ids"] = ( + "table_ids" in data["form"] and data["form"]["table_ids"] or False + ) + return result + + @staticmethod + def _transform_binary(binary): + # TODO: Implement if needed + return False + + def _clean_data(self, model, rows): + cleaned_rows = [] + for i, row in enumerate(rows): + cleaned_rows.append({}) + for key, value in row.items(): + label = self.env[model]._fields[key].string or key + if self.env[model]._fields[key].store: + if "many2one" == self.env[model]._fields[key].type: + comodel = self.env[model]._fields[key].comodel_name + if value: + record = self.env[comodel].sudo().browse(value) + cleaned_rows[i][label] = record.display_name + else: + cleaned_rows[i][label] = rows[i][key] + elif "binary" == self.env[model]._fields[key].type: + binary = self._transform_binary(rows[i][key]) + if binary: + cleaned_rows[i][label] = binary + elif "2many" not in self.env[model]._fields[key].type: + cleaned_rows[i][label] = rows[i][key] + return cleaned_rows + + def check_report(self, xlsx_report=False): + self.ensure_one() + data = {} + data["ids"] = self.env.context.get("active_ids", []) + data["model"] = self.env.context.get("active_model", "ir.ui.menu") + data["form"] = self.read(["partner_id", "company_id", "table_ids"])[0] + used_context = self._build_contexts(data) + data["form"]["id"] = str(data["form"]["id"]) + data["form"]["used_context"] = dict( + used_context, lang=self.env.context.get("lang", "en_US") + ) + return self._print_report(data=data, xlsx_report=xlsx_report) + + def compute_data_for_report(self, data): + if not data.get("form"): + raise UserError( + _("Form content is missing, this report cannot be printed.") + ) + partner = data["form"].get("partner_id", False) + if not partner: + raise UserError(_("No provided partner.")) + partner = self.env["res.partner"].sudo().browse(partner[0]) + tables = data["form"].get("table_ids", False) + if tables: + tables = self.env["privacy.partner.data"].browse(tables) + tables = self._get_rows_from_tables(tables, partner) + data.update({"tables": tables}) + return data + + def _exclude_column(self, model, column): + + # https://github.com/odoo/odoo/issues/24927 + if model in ("mail.compose.message", "survey.mail.compose.message"): + if column in ("needaction_partner_ids", "starred_partner_ids"): + return True + # feel free to add more specific cases meanwhile the issue is not fixed + + return False + + def _get_default_table(self, name, data): + if data: + field_type = data[0][4] + res = self.env[data[0][1]] + for t in data: + res |= self.env[t[1]].sudo().browse(t[3]) + if res: + values = { + "name": name, + "model_id": self.env["ir.model"] + .sudo() + .search([("model", "=", res._name)]) + .id, + "count_rows": len(res.ids), + "field_type": field_type, + "res_ids": res.ids, + } + return values + return {} + + def _get_model_from_table(self, table, partner): + new_tables = {} + for model in table.model_id: + rows = self._get_rows_from_model(model, partner) + new_tables[model.display_name] = rows + return new_tables + + def _get_rows_from_model(self, model, partner): + lines = self.env[model.model] + columns = [ + k + for k, v in self.env[model.model]._fields.items() + if v.comodel_name == "res.partner" + and v.store + and not self._exclude_column(model.model, k) + ] + for column in columns: + lines |= self.env[model.model].sudo().search([(column, "=", partner.id)]) + rows = lines.sudo().read(load=False) + rows = self._clean_data(model.model, rows) + return rows + + def _get_rows_from_tables(self, tables, partner): + new_tables = {} + for table in tables: + data_table = self._get_model_from_table(table, partner) + new_tables[str(table.name)] = data_table + return new_tables + + def _get_table_names(self, data): + names = [] + for t in data: + if t[3] and not t[5] and t[0] not in names: + names.append(t[0]) + return names + + def _get_tables_from_partner(self, partner): + tables = [ + t[0] + for t in [ + [ + [ + self.env[m]._table, + m, + k, + self.env[m].sudo().search([(k, "=", partner.id)]).ids, + v.type, + self.env[m]._transient, + ] + for k, v in self.env[m]._fields.items() + if v.comodel_name == "res.partner" + and self.env[m]._auto + and v.store + and not self._exclude_column(m, k) + ] + for m in [x for x in self.env.registry.keys()] + ] + if t + ] + for i, t in enumerate(tables): + if t[4] == "many2many": + if t[3]: + relation = self.env[t[1]]._fields[t[2]].relation + if relation: + tables[i][0] = relation + return tables + + def _print_report(self, data, xlsx_report=False): + records = self.env[data["model"]].sudo().browse(data.get("ids", [])) + if xlsx_report: + return ( + self.env.ref("privacy_partner_report.report_partner_xlsx") + .with_context(landscape=True) + .report_action(records, data=data) + ) + + +class PrivacyPartnerData(models.TransientModel): + _name = "privacy.partner.data" + _description = "Privacy Partner Data" + + name = fields.Char(string="Database Table",) + model_id = fields.Many2one( + comodel_name="ir.model", ondelete="cascade", string="Models", + ) + field_type = fields.Char(string="Type", oldname="type",) + count_rows = fields.Integer(default=0, string="Number of lines",) + res_ids = fields.Char( + "Related Document IDs", index=True, help="List of Related Document IDs" + ) + + def action_view_records(self): + self.ensure_one() + response = { + "name": self.model_id.display_name, + "type": "ir.actions.act_window", + "res_model": self.model_id.model, + "view_mode": "tree,form", + "domain": [("id", "in", ast.literal_eval(self.res_ids))], + "target": "current", + "context": {"delete": True}, + } + return response diff --git a/privacy_partner_report/wizard/privacy_report_partner_wizard.xml b/privacy_partner_report/wizard/privacy_report_partner_wizard.xml new file mode 100644 index 0000000..c96863c --- /dev/null +++ b/privacy_partner_report/wizard/privacy_report_partner_wizard.xml @@ -0,0 +1,75 @@ + + + + Partner Report + privacy.partner.report + +
+
+
+ + + Select a company +
+ +
+
+ + + Select a partner +
+ +
+
+ + + + + +